JavaScript中的異步隊列

而在JavaScript中有兩種異步宏任務(wù)macro-task和微任務(wù)micro-task.

在掛起任務(wù)時,JS 引擎會將所有任務(wù)按照類別分到這兩個隊列中,首先在 macrotask 的隊列(這個隊列也被叫做 task queue)中取出第一個任務(wù),執(zhí)行完畢后取出 microtask 隊列中的所有任務(wù)順序執(zhí)行;之后再取 macrotask 任務(wù),周而復(fù)始,直至兩個隊列的任務(wù)都取完。

常見的異步代碼實現(xiàn)
macro-task: script(整體代碼), setTimeout, setInterval, setImmediate, I/O, UI rendering

micro-task: process.nextTick, Promises(原生 Promise), Object.observe(api已廢棄), MutationObserver

setTimeout(function() {
  console.log(1)
}, 0);
new Promise(function executor(resolve) {
  console.log(2);
  for( var i=0 ; i<10000 ; i++ ) {
    i == 9999 && resolve();
  }
  console.log(3);
}).then(function() {
  console.log(4);
});
console.log(5);
// 2 3 5 4 1
  1. 第一次整體代碼進(jìn)入macro-task。micro-task為空。
  2. macro-task執(zhí)行整體代碼,setTimeout加入下一次的macro-task。Promise執(zhí)行打出2 3,then加入micro-task, 最后打出5。
  3. micro-task執(zhí)行then被執(zhí)行所以打出4。
  4. 重新執(zhí)行macro-task所以打出1

Promise執(zhí)行流程

  1. new Promise(func:(resolve, reject)=> void 0), 這里的func方法被同步執(zhí)行。
  2. Promise 會有三種狀態(tài)PENDING(執(zhí)行),F(xiàn)ULFILLED(執(zhí)行成功),REJECTED(執(zhí)行失敗)。
  3. 在resolve,reject均未調(diào)用且未發(fā)生異常時狀態(tài)為PENDING。
  4. resolve調(diào)用為FULFILLED,reject調(diào)用或者發(fā)生異常為REJECTED。
  5. 在給Promise實例調(diào)用then(callFulfilled, callRejected)來設(shè)置回調(diào),狀態(tài)不為PENDING時會根據(jù)狀態(tài)調(diào)用callFulfilled和callRejected。
  6. then需要返回一個新的Promise實例.
  7. 狀態(tài)為PENDING則會把callFulfilled和callRejected放入當(dāng)前Promise實例的回調(diào)隊列中,隊列還會存儲新的Promise實例。
  8. 在狀態(tài)改變?yōu)镕ULFILLED或REJECTED時會回調(diào)當(dāng)前Promise實例的隊列。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容