• <noscript id="ggggg"><dd id="ggggg"></dd></noscript>
    <small id="ggggg"></small> <sup id="ggggg"></sup>
    <noscript id="ggggg"><dd id="ggggg"></dd></noscript>
    <tfoot id="ggggg"></tfoot>
  • <nav id="ggggg"><cite id="ggggg"></cite></nav>
    <nav id="ggggg"></nav>
    成人黃色A片免费看三更小说,精品人妻av区波多野结衣,亚洲第一极品精品无码,欧美综合区自拍亚洲综合,久久99青青精品免费观看,中文字幕在线中字日韩 ,亚洲国产精品18久久久久久,黄色在线免费观看

    Promise 你真的用明白了么?

    2020-9-2    seo達(dá)人

    前置知識(shí)

    在開始正文前,我們先把本文涉及到的一些內(nèi)容提前定個(gè)基調(diào)。

    Promise 哪些 API 涉及了微任務(wù)?

    Promise 中只有涉及到狀態(tài)變更后才需要被執(zhí)行的回調(diào)才算是微任務(wù),比如說 then、 catch 、finally ,其他所有的代碼執(zhí)行都是宏任務(wù)(同步執(zhí)行)。

    上圖中藍(lán)色為同步執(zhí)行,黃色為異步執(zhí)行(丟到微任務(wù)隊(duì)列中)。

    這些微任務(wù)何時(shí)被加入微任務(wù)隊(duì)列?

    這個(gè)問題我們根據(jù) ecma 規(guī)范來看:

    • 如果此時(shí) Promise 狀態(tài)為 pending,那么成功或失敗的回調(diào)會(huì)分別被加入至 [[PromiseFulfillReactions]] 和 [[PromiseRejectReactions]] 中。如果你看過手寫 Promise 的代碼的話,應(yīng)該能發(fā)現(xiàn)有兩個(gè)數(shù)組存儲(chǔ)這些回調(diào)函數(shù)。
    • 如果此時(shí) Promise 狀態(tài)為非 pending 時(shí),回調(diào)會(huì)成為 Promise Jobs,也就是微任務(wù)。

    了解完以上知識(shí)后,正片開始。

    同一個(gè) then,不同的微任務(wù)執(zhí)行

    初級

    Promise.resolve()
      .then(() => { console.log("then1"); Promise.resolve().then(() => { console.log("then1-1");
        });
      })
      .then(() => { console.log("then2");
      });

    以上代碼大家應(yīng)該都能得出正確的答案:then1 → then1-1 → then2

    雖然 then 是同步執(zhí)行,并且狀態(tài)也已經(jīng)變更。但這并不代表每次遇到 then 時(shí)我們都需要把它的回調(diào)丟入微任務(wù)隊(duì)列中,而是等待 then 的回調(diào)執(zhí)行完畢后再根據(jù)情況執(zhí)行對應(yīng)操作。

    基于此,我們可以得出第一個(gè)結(jié)論:鏈?zhǔn)秸{(diào)用中,只有前一個(gè) then 的回調(diào)執(zhí)行完畢后,跟著的 then 中的回調(diào)才會(huì)被加入至微任務(wù)隊(duì)列。

    中級

    大家都知道了 Promise resolve 后,跟著的 then 中的回調(diào)會(huì)馬上進(jìn)入微任務(wù)隊(duì)列。

    那么以下代碼你認(rèn)為的輸出會(huì)是什么?

    let p = Promise.resolve();
    
    p.then(() => { console.log("then1"); Promise.resolve().then(() => { console.log("then1-1");
      });
    }).then(() => { console.log("then1-2");
    });
    
    p.then(() => { console.log("then2");
    }); 

    按照一開始的認(rèn)知我們不難得出 then2 會(huì)在 then1-1 后輸出,但是實(shí)際情況卻是相反的。

    基于此我們得出第二個(gè)結(jié)論:每個(gè)鏈?zhǔn)秸{(diào)用的開端會(huì)首先依次進(jìn)入微任務(wù)隊(duì)列。

    接下來我們換個(gè)寫法:

    let p = Promise.resolve().then(() => { console.log("then1"); Promise.resolve().then(() => { console.log("then1-1");
      });
    }).then(() => { console.log("then2");
    });
    
    p.then(() => { console.log("then3");
    });

    上述代碼其實(shí)有個(gè)陷阱,then 每次都會(huì)返回一個(gè)新的 Promise,此時(shí)的 p 已經(jīng)不是 Promise.resolve() 生成的,而是最后一個(gè) then 生成的,因此 then3 應(yīng)該是在 then2 后打印出來的。

    順便我們也可以把之前得出的結(jié)論優(yōu)化為:同一個(gè) Promise 的每個(gè)鏈?zhǔn)秸{(diào)用的開端會(huì)首先依次進(jìn)入微任務(wù)隊(duì)列。

    高級

    以下大家可以猜猜 then1-2 會(huì)在何時(shí)打印出來?

    Promise.resolve()
      .then(() => { console.log("then1"); Promise.resolve()
          .then(() => { console.log("then1-1"); return 1;
          })
          .then(() => { console.log("then1-2");
          });
      })
      .then(() => { console.log("then2");
      })
      .then(() => { console.log("then3");
      })
      .then(() => { console.log("then4");
      });

    這題肯定是簡單的,記住第一個(gè)結(jié)論就能得出答案,以下是解析:

    • 第一次 resolve 后第一個(gè) then 的回調(diào)進(jìn)入微任務(wù)隊(duì)列并執(zhí)行,打印 then1
    • 第二次 resolve 后內(nèi)部第一個(gè) then 的回調(diào)進(jìn)入微任務(wù)隊(duì)列,此時(shí)外部第一個(gè) then 的回調(diào)全部執(zhí)行完畢,需要將外部的第二個(gè) then 回調(diào)也插入微任務(wù)隊(duì)列。
    • 執(zhí)行微任務(wù),打印 then1-1 和 then2,然后分別再將之后 then 中的回調(diào)插入微任務(wù)隊(duì)列
    • 執(zhí)行微任務(wù),打印 then1-2 和 then3 ,之后的內(nèi)容就不一一說明了

    接下來我們把 return 1 修改一下,結(jié)果可就大不相同啦:

    Promise.resolve()
      .then(() => { console.log("then1"); Promise.resolve()
          .then(() => { console.log("then1-1"); return Promise.resolve();
          })
          .then(() => { console.log("then1-2");
          });
      })
      .then(() => { console.log("then2");
      })
      .then(() => { console.log("then3");
      })
      .then(() => { console.log("then4");
      });

    當(dāng)我們 return Promise.resolve() 時(shí),你猜猜 then1-2 會(huì)何時(shí)打印了?

    答案是最后一個(gè)才被打印出來。

    為什么在 then 中分別 return 不同的東西,微任務(wù)的執(zhí)行順序竟有如此大的變化?以下是筆者的解析。

    PS:then 返回一個(gè)新的 Promise,并且會(huì)用這個(gè) Promise 去 resolve 返回值,這個(gè)概念需要大家先了解一下。

    根據(jù) Promise A+ 規(guī)范

    根據(jù)規(guī)范 2.3.2,如果 resolve 了一個(gè) Promise,需要為其加上一個(gè) then 并 resolve

    if (x instanceof MyPromise) { if (x.currentState === PENDING) {
      } else {
        x.then(resolve, reject);
      } return;
    }

    上述代碼節(jié)選自手寫 Promise 實(shí)現(xiàn)。

    那么根據(jù) A+ 規(guī)范來說,如果我們在 then 中返回了 Promise.resolve 的話會(huì)多入隊(duì)一次微任務(wù),但是這個(gè)結(jié)論還是與實(shí)際不符的,因此我們還需要尋找其他權(quán)威的文檔。

    根據(jù) ECMA - 262 規(guī)范

    根據(jù)規(guī)范 25.6.1.3.2,當(dāng) Promise resolve 了一個(gè) Promise 時(shí),會(huì)產(chǎn)生一個(gè)NewPromiseResolveThenableJob,這是屬于 Promise Jobs 中的一種,也就是微任務(wù)。

    This Job uses the supplied thenable and its then method to resolve the given promise. This process must take place as a Job to ensure that the evaluation of the then method occurs after evaluation of any surrounding code has completed.

    并且該 Jobs 還會(huì)調(diào)用一次 then 函數(shù)來 resolve Promise,這也就又生成了一次微任務(wù)。

    這就是為什么會(huì)觸發(fā)兩次微任務(wù)的來源。

    藍(lán)藍(lán)設(shè)計(jì)m.lzhte.cn )是一家專注而深入的界面設(shè)計(jì)公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計(jì)、BS界面設(shè)計(jì) 、 cs界面設(shè)計(jì) 、 ipad界面設(shè)計(jì) 、 包裝設(shè)計(jì) 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計(jì)、 網(wǎng)站建設(shè) 平面設(shè)計(jì)服務(wù)

    日歷

    鏈接

    個(gè)人資料

    存檔

    主站蜘蛛池模板: 欧美%20亚洲%20国产%20丝袜%20在线 | 国产精品日本一区二区不卡视频 | 都市激情第一页| 麻豆精品国产自产在线| 四虎三级在线视频播放| 午夜精品久久久久久久久日韩欧美 | 国产精品乱子乱XXXX| 国产精品特级毛片一区二区三区 | 欧美成人免费午夜全| 亚洲天堂网在线视频| 亚洲综合网美国十次| 成人无码区免费视频网站蜜臀| 一本一道久久a久久精品综合| 久久久综合亚洲色一区二区三区| 日本香蕉久久一区二区视频| 日本黄色三级网站| 邻居少妇张开腿让我爽了在线观看 | 无码国产精品免费看| 欧美激烈精交gif动态图| 国产成人h在线视频| 成人福利国产午夜AV免费不卡在线 | 欧美一级特黄aaaaaa在线看片| 在线播放亚洲一区蜜臀| 亚洲精品乱码久久久久久麻豆不卡| 精品91亚洲高清在线观看| 欧美a级在线现免费观看| 福利精品一区二区三区| 国产亚洲欧美日韩国产片| 久久精品99久久香蕉国产| 激,情四虎欧美视频图片| 激情亚洲的在线观看| 国产在线观看精品一区二区三区| 欧美一级鲁丝片免费一区| 9丨精品国产高清自在线看| 99久久国语露脸精品国产| 精品精品国产欧美在线| 色欲网天天无码av| 中文国产成人精品久久水| 不卡国产精品爽黄69天堂a| 日韩国产精品自在自线| 看久久久久久一级毛片|