我在學習異步 javascript 時頭暈目眩。我在異步函式中有以下代碼:
const promise1 = () => {
return new Promise((resolve, _reject) => {
setTimeout(resolve, 3000);
});
};
const promise2 = () => {
return new Promise((resolve, _reject) => {
setTimeout(resolve, 1000);
});
};
await promise1();
console.log(1);
await promise2();
console.log(2);
它按我的預期作業:“等待 3 秒鐘,同步執行某些操作,然后等待 1 秒鐘,然后執行同步執行的操作”。但是如果我將兩個常量從匿名函式運算式更改為 Promise 建構式
const promise3 = new Promise((resolve, _reject) => {
setTimeout(resolve, 3000);
});
const promise4 = new Promise((resolve, _reject) => {
setTimeout(resolve, 1000);
});
并將其稱為
await promise3;
console.log(3);
await promise4;
console.log(4);
我的邏輯失敗 - 第二個 console.log(3) 立即執行,沒有 1 秒延遲。
但是,如果我回傳第一個代碼并更改超時延遲,使第一個延遲小于第二個(即第一個超時延遲 2000 毫秒,第二個將是 3000) - 第二個 console.log(2) 在 3000-2000 之間的時間差后執行=1000 毫秒。
有人可以詳細解釋它是如何作業的嗎?我發現,這就是事件回圈中的微任務和宏任務的全部內容,但不明白,為什么我會得到這個結果。
PS我知道,這兩個 await 都可以替換為:
delay(ms1)
.tnen(() =>{
console.log('some1');
return delay(ms2);
})
.then(() =>{
console.log('some2')
})
只需要通過 async\await 理解事件回圈的深層機制;
uj5u.com熱心網友回復:
我發現,這就是事件回圈中的微任務和宏任務...
并不真地。關鍵的一點是,Promise建構式呼叫傳遞給它(承諾執行程式功能)功能立即和同步。因此計時器在您執行時啟動new Promise,而不是在您使用時await啟動,因此您將一個接一個地啟動兩個計時器。相比之下,您的第一個代碼塊new Promise直到第一個計時器觸發后才呼叫啟動第二個計時器,因為您在呼叫promise2()獲取第二個計時器的承諾之前等待第一個結果(這就是啟動它的原因)。
讓我們來看看,在動作中加入某些記錄(我已經改變了promise1對function和promise2對function2的,因為他們不承諾,他們是函式):
(async () => {
const start = Date.now();
const log = (...msgs) => console.log(String(Date.now() - start).padStart(4, "0"), ...msgs);
const function1 = () => {
log("function1 called");
return new Promise((resolve, _reject) => {
log("starting 3000ms timer");
setTimeout(() => {
log("fulfilling 3000ms timer");
resolve();
}, 3000);
});
};
const function2 = () => {
log("function1 called");
return new Promise((resolve, _reject) => {
log("starting 1000ms timer");
setTimeout(() => {
log("fulfilling 1000ms timer");
resolve();
}, 1000);
});
};
log("Calling and waiting on function1");
await function1();
log(1);
log("Calling and waiting on function2");
await function2();
log(2);
log("Creating promise3");
const promise3 = new Promise((resolve, _reject) => {
log("starting 3000ms timer");
setTimeout(() => {
log("fulfilling 3000ms timer");
resolve();
}, 3000);
});
log("Creating promise4");
const promise4 = new Promise((resolve, _reject) => {
log("starting 1000ms timer");
setTimeout(() => {
log("fulfilling 1000ms timer");
resolve();
}, 1000);
});
log("Waiting for promise3");
await promise3;
log(3);
log("Waiting for promise4");
await promise4;
log(4);
})();
.as-console-wrapper {
max-height: 100% !important;
}
有了這個,我們得到了這樣的輸出:
0000 呼叫并等待函式 1 0001 函式 1 呼叫 0001 啟動 3000ms 定時器 3003 完成 3000ms 定時器 3004 1 3006 呼叫并等待函式 2 3008 函式 1 被呼叫 3009 啟動 1000ms 定時器 4011 完成 1000ms 定時器 4012 2 4014 創建promise3 4016 啟動 3000ms 定時器 4017 創建promise4 4019 啟動 1000ms 定時器 4020 等待promise3 5020 完成 1000ms 定時器 7018 完成 3000ms 定時器 7019 3 7021 等待promise4 7023 4
請注意如何promise3和promise4都啟動了定時器馬上重疊他們。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/403383.html
標籤:
