欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中Promise的執(zhí)行順序舉例詳析

 更新時間:2025年05月09日 10:10:33   作者:mosen868  
這篇文章主要介紹了JavaScript中Promise執(zhí)行順序的相關(guān)資料,通過示例代碼分析,展示了同步任務(wù)、微任務(wù)和宏任務(wù)的執(zhí)行順序,并解釋了為什么第一個then返回Promise時,輸出順序會發(fā)生變化,文中介紹的非常詳細,需要的朋友可以參考下

概述

理解 Promise 的執(zhí)行順序時,需要牢記以下兩點:

  • 微任務(wù)與宏任務(wù)的優(yōu)先級

    • 微任務(wù):Promise.then()、catch、finally 是微任務(wù)。
    • 宏任務(wù):setTimeoutsetInterval 是宏任務(wù)。
    • 微任務(wù)的優(yōu)先級高于宏任務(wù):在一次事件循環(huán)中,先清空所有的微任務(wù)隊列,再執(zhí)行下一個宏任務(wù)。
  • Promise 是基于微任務(wù)實現(xiàn)的

    • 當(dāng)一個 Promise 的狀態(tài)變?yōu)?nbsp;resolved 或 rejected 時,它的 .then() 回調(diào)會被加入微任務(wù)隊列,等待當(dāng)前任務(wù)(包括微任務(wù))完成后執(zhí)行。

示例代碼分析

代碼分析

以下代碼可以幫助理解 Promise 和 setTimeout 的執(zhí)行順序:

console.log("script start");

setTimeout(() => {
  console.log("setTimeout 1");
}, 0);

Promise.resolve()
  .then(() => {
    console.log("promise 1");
    return Promise.resolve().then(() => {
      console.log("promise 2");
    });
  })
  .then(() => {
    console.log("promise 3");
  });

setTimeout(() => {
  console.log("setTimeout 2");
}, 0);

console.log("script end");

執(zhí)行過程解析

  • 同步任務(wù):立即執(zhí)行

    • console.log("script start") 輸出 "script start".
    • setTimeout 的兩個回調(diào)函數(shù)被放入 宏任務(wù)隊列,等待事件循環(huán)調(diào)度。
    • Promise.resolve() 被調(diào)用,then() 的回調(diào)被放入 微任務(wù)隊列。

    輸出結(jié)果:

  • script start
    script end

  • 主線程執(zhí)行完同步任務(wù)后,開始執(zhí)行微任務(wù)隊列

    • 微任務(wù)隊列的順序如下:
      • 第一個 .then() 輸出 "promise 1" 并返回一個新的 Promise。
      • 新的 Promise.then() 輸出 "promise 2"。
      • 第二個 .then() 輸出 "promise 3"

    輸出結(jié)果:

    promise 1
    promise 2
    promise 3
    
  • 清空微任務(wù)隊列后,開始執(zhí)行宏任務(wù)隊列

    • 宏任務(wù)隊列的兩個 setTimeout 回調(diào)依次執(zhí)行,輸出 "setTimeout 1" 和 "setTimeout 2"。

    輸出結(jié)果:

    setTimeout 1
    setTimeout 2
    

最終輸出

綜合以上,代碼的輸出順序為:

script start
script end
promise 1
promise 2
promise 3
setTimeout 1
setTimeout 2

總結(jié)

  • 同步任務(wù)優(yōu)先執(zhí)行,輸出 script start 和 script end。
  • 微任務(wù)隊列優(yōu)先于宏任務(wù)隊列。
  • Promise.then() 的回調(diào)會依次進入微任務(wù)隊列。
  • setTimeout 的回調(diào)進入宏任務(wù)隊列,最后執(zhí)行。

(拓展)問題補充

如果第一個then不是返回return promise,而是直接執(zhí)行一個Promise.resolve().then(() => { console.log("promise 2"); });結(jié)果是不是
會變成 promise 1 → promise 3 → promise 2。結(jié)果是的。

為什么會這樣?

當(dāng) Promise.resolve().then() 不通過 return 將內(nèi)部的 Promise 鏈接到外部 then 時,promise 2 的執(zhí)行不再是當(dāng)前鏈的一部分,它會被單獨添加到 微任務(wù)隊列的末尾,導(dǎo)致執(zhí)行順序的變化。

示例代碼

以下是修改后的代碼:

console.log("script start");

Promise.resolve()
  .then(() => {
    console.log("promise 1");
    Promise.resolve().then(() => {
      console.log("promise 2");
    });
  })
  .then(() => {
    console.log("promise 3");
  });

console.log("script end");

執(zhí)行過程解析

  • 同步任務(wù)

    • 輸出 "script start"。
    • 主線程繼續(xù),將第一個 Promise.then() 的回調(diào)加入 微任務(wù)隊列。
    • 輸出 "script end"。

    當(dāng)前輸出:

    script start
    script end
    
  • 微任務(wù)隊列開始執(zhí)行

    • 執(zhí)行第一個 .then(),輸出 "promise 1"。
      在此回調(diào)中,一個新的微任務(wù)promise 2 的回調(diào))被加入 微任務(wù)隊列末尾。
    • 執(zhí)行第二個 .then() 的回調(diào),輸出 "promise 3"。

    當(dāng)前輸出:

    promise 1
    promise 3
    
  • 微任務(wù)隊列剩余任務(wù)

    • 微任務(wù)隊列中剩余的任務(wù)是 promise 2 的回調(diào),輸出 "promise 2"。

    最終輸出:

    promise 2
    

總輸出結(jié)果

綜合以上,完整的輸出順序是:

script start
script end
promise 1
promise 3
promise 2

關(guān)鍵點解析

  • 鏈?zhǔn)秸{(diào)用和微任務(wù)隊列當(dāng)你不通過 return 將一個新的 Promise 鏈接到當(dāng)前 then,它的回調(diào)會獨立加入 微任務(wù)隊列的末尾,而不是成為當(dāng)前鏈的一部分。

  • 對比:返回 Promise如果 return Promise.resolve().then(...),那么 promise 2 的執(zhí)行會成為當(dāng)前鏈的一部分,順序為 promise 1 → promise 2 → promise 3

改變的核心代碼

  • 獨立的微任務(wù):

    Promise.resolve().then(() => {
      console.log("promise 2");
    });
    
  • 作為鏈的一部分:

    return Promise.resolve().then(() => {
      console.log("promise 2");
    });
    

兩種寫法的區(qū)別在于是否將新的 Promise 加入當(dāng)前鏈。

總結(jié)

到此這篇關(guān)于JavaScript中Promise的執(zhí)行順序舉例詳析的文章就介紹到這了,更多相關(guān)JS Promise執(zhí)行順序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論