多個(gè)異步同時(shí)執(zhí)行 Promise.all
function promiseFn1(){
return new Promise(resolve =>{
setTimeout(() => {
resolve("result");
}, 1000);
});
}
function promiseFn2(){
return new Promise(resolve =>{
setTimeout(() => {
resolve("result");
}, 2000);
})
}
async function func1(){
console.time("func1");
const res1 = await promiseFn1();
const res2 = await promiseFn2();
console.timeEnd("func1");
}
async function func2(){
console.time("func2");
const [res1,res2] = await Promise.all([promiseFn1(), promiseFn2()]);
console.timeEnd("func2");
}
func1(); // func1: 3002.159912109375ms
func2(); // func2: 2001.130126953125ms
Object.values 遍歷對象的值 | Object.entries 遍歷對象的鍵值
const obj = {name:'marisol', age:'23'}
// Object.values 遍歷對象中的值
console.log(Object.values(obj)); // [ 'marisol', '23' ]
// Object.entries 遍歷對象的鍵值對
console.log(Object.entries(obj)); // [ [ 'name', 'marisol' ], [ 'age', '23' ] ]
// 需求 遍歷出對象的鍵值
for ([key,value] of Object.entries(obj)){
console.log(`${key}-${value}`);
}
// name-marisol
// age-23
對象的擴(kuò)展 getOwnPropertyDescriptors(obj)
獲取對象的所有自身屬性的描述符
用它可以實(shí)現(xiàn)對象的淺拷貝
Object.assign()只能拷貝對象的自身可枚舉屬性,不能拷貝對象的屬性特性,而且訪問器屬性會被轉(zhuǎn)化成數(shù)據(jù)屬性,無法拷貝源對象原型,使用Object.getOwnPropertyDescriptors()搭配Object.create()就能實(shí)現(xiàn)上述功能。
const newObj = Object.create(
Object.getPrototypeOf(myObj),
Object.getOwnPropertyDescriptors(myObj),
);
全局對象SharedArrayBuffer 與 Atomics
給JS帶來了多線程的功能,高級特性,JS引擎核心改進(jìn)
共享內(nèi)存的主要思想就是把多線程引入JS
postMessage()
多線程的競爭問題:使用Atomics解決
首先用Worker和message實(shí)現(xiàn)通信
// main.js
// 創(chuàng)建一個(gè)worker進(jìn)程
const worker = new Worker('./worker.js');
// postMessage
// 向worker發(fā)消息
worker.postMessage('hello i am main');
// 接收到worker的消息
worker.onmessage = function(e){
console.log(e.data);
}
// worker.js
// message事件
onmessage = function(e){
console.log(e.data);;
postMessage('hello i am worker');
}
<!-- index.html -->
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="main.js"></script>
<title>Document</title>
</head>
<body>
</body>
</html>
就這樣用node main.js 命令運(yùn)行還不行 老師起了一個(gè)http-server 服務(wù)
http-server // 命令行執(zhí)行
npm install http-server -g// 如果沒有安裝http-server 需要先安裝
啟動(dòng)之后去訪問服務(wù)的地址就好了
SharedArrayBuffer 共享內(nèi)存
Atomics 原子操作,是操作的最小單位,不會被打斷,一個(gè)一個(gè)的執(zhí)行
// main.js
const worker = new Worker('./worker.js');
// 新建1kb共享內(nèi)存
const sharedBuffer = new SharedArrayBuffer(1024);
// 創(chuàng)建視圖
const intArrBuffer = new Int32Array(sharedBuffer);
for(let i=0; i<intArrBuffer.length; i++) {
intArrBuffer[i] = i;
}
worker.postMessage(intArrBuffer);
worker.onmessage = function(e){ // 在worker進(jìn)程中可以對共享內(nèi)存進(jìn)行修改
console.log('更改后的數(shù)據(jù):', intArrBuffer[20]); // 111
}
// worker.js
onmessage = function(e){
let arrBuffer = e.data;
// console.log(arrBuffer[20]); // undefined 這樣取值是不對的
console.log(Atomics.load(arrBuffer, 20));
// arrBuffer[20] = 80; // 操作無效 這樣存值是不對的
// 直接修改共享內(nèi)存中的數(shù)據(jù) main.js 中查詢的數(shù)據(jù)也會被改變
console.log(Atomics.store(arrBuffer, 20, 99)); // 99 返回存入的新數(shù)據(jù)
console.log(Atomics.exchange(arrBuffer, 20, 111)); // 99 返回被替代下來的舊數(shù)據(jù)
postMessage('hello i am worker!');
}
Atomics.wait 休眠
onmessage = function(e){
let arrBuffer = e.data;
Atomics.wait(arrBuffer, 11, 11); // 滿足當(dāng)arrBuffer 中index為11的值為11時(shí),會休眠
console.log("我已經(jīng)休眠了,不會被執(zhí)行");
}
onmessage = function(e) {
let arrBuffer = e.data;
Atomics.wait(arrBuffer, 11, 11, 2000); // 休眠兩秒然后執(zhí)行
console.log('i am sleeping and will not run!')
}
// index.js 主線程中喚醒worker線程
worker.postMessage(intArrBuffer);
setTimeout(() => {
// 三個(gè)參數(shù)
// 共享內(nèi)存的視圖數(shù)組
// Index: 視圖數(shù)據(jù)位置
// count:喚醒的worker進(jìn)程數(shù),默認(rèn)infinity
Atomics.notify(intArrBuffer, 11 , 1);
}, 3000);