簡體   English   中英

為什么在b打印之前打印2和4張?

[英]why 2 and 4 prints before b prints?

 function first() { return new Promise(resolve => { console.log(2); resolve(3); console.log(4); }); } async function f() { console.log(1); let r = await first(); console.log(r); console.log(99); } console.log('a'); f(); console.log('b'); 

在上面的代碼中顯示了以下結果:

a
1
2
4
b
3
99

以我的理解,當編譯器點擊await first()函數時,它將first()函數的執行推入事件隊列並暫停f()的執行,繼續執行f()之后的所有內容,因此執行順序應為:

a
1
b
2
4
3
99

顯然,我理解錯了。 誰能向我解釋這是如何工作的?

在此處輸入圖片說明

在此處輸入圖片說明

如果您聽不懂,請發表評論。 謝謝。

我認為這實際上正在發生,請查看注釋和數字

function first() {
  return new Promise(resolve => {
    console.log(2); // 5. Print "2"
    resolve(3); // 6. call resolve(3), meaning it will set the resolveCallback state of Promise with 3. 
    console.log(4); // 7. print "4"
  });
}

async function f() {
  console.log(1); // 3. Print "1"
  let r = await first(); // 4. Call the first() method and await the result, control goes to first() 
                        // 8. Since first() method updated the state of resolveCallback, it will assign "3" to variable "r" 
  console.log(r); // 10. print "3" 
  console.log(99); // 11. print "99"
}

console.log('a'); // 1. Start print 'a'
f(); // 2. Since funtion f() is decoreated with async key word it is by default return a promise and control goes to f()
console.log('b'); // 9. Since control release from f() print "b"

簡單來說,Promise允許您異步運行某些代碼 ,然后在完成后並根據結果(是否成功或失敗)運行其他代碼,它是使用構造函數模式創建的。

簽名: 函數(resolveCallback,rejectCallback)

構造函數返回一個Promise對象,該對象跟蹤其state ,並且只能穩定一次。 這意味着解析器和拒絕器功能一起只能接收一個呼叫,並且狀態不能從已解決變為拒絕,反之亦然。

await表達式會導致異步功能的執行暫停,直到Promise被解決為止。一旦諾言被兌現或被拒絕,然后它將繼續執行異步功能。與此同時,它將繼續在異步功能之外執行代碼。

查看有關Promise的executor參數的MDN文章。

執行器功能被立即調用,即同步調用。

await基本上是等待一個promise解析/拒絕,但是在await語句之后立即執行的同步代碼。

同樣,取f()調用,請注意,你有1控制台后a立即雖然async函數返回一個承諾。

好吧,它需要對javascript中的“任務和微任務執行”有深入的了解。 每個諾言都是通過在每個任務結束時運行的一些微任務隊列來處理的。

根據文檔,只要沒有其他JavaScript在執行中間,並且在每個任務結束時,都會在回調之后處理微任務隊列。 在微任務期間排隊的所有其他微任務都將添加到隊列的末尾並進行處理。

您可以在https://javascript.info/microtask-queue上找到最佳解釋。

如果您擔心執行順序,請在Promise中使用setTimeout。 setTimeout為它的回調計划一個新任務,因此在這種情況下它將在當前任務之后運行

function first() {
  return new Promise(resolve => { setTimeout(()=>{
    console.log(2);
    resolve(3);
    console.log(4);
  }); });
}

async function f() {
  console.log(1);
  let r = await first();
  console.log(r);
  console.log(99);
}

console.log('a');
f();
console.log('b');

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM