日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
一篇文章帶你搞懂JavaScript微任務(wù)(Microtask)

大家好,我進(jìn)階學(xué)習(xí)者。

創(chuàng)新互聯(lián)是一家專注于網(wǎng)站設(shè)計、成都做網(wǎng)站與策劃設(shè)計,豐林網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:豐林等地區(qū)。豐林做網(wǎng)站價格咨詢:028-86922220

一、前言

Promise 處理始終是異步的,因為所有 promise 行為都會通過內(nèi)部的 “promise jobs” 隊列,也被稱為“微任務(wù)隊列”。

Promise 的處理程序(handlers).then、.catch 和 .finally 都是異步的。

即便一個 promise 立即被 resolve,.then、.catch 和 .finally ,下面的代碼也會在這些處理程序(handler)之前被執(zhí)行。

代碼如下:

 
 
 
 
  1. let promise = Promise.resolve(); 
  2. promise.then(() => alert("promise done!")); 
  3. alert("code finished");  
  4. // 這個 alert 先顯示 

如果運行它,會首先看到 code finished,然后才是 promise done。這很奇怪,因為這個 promise 肯定是一開始就完成的。

運行結(jié)果:

為什么 .then 會在之后才被觸發(fā)?這是怎么回事?

二、微任務(wù)隊列(Microtask queue)

1. 如果執(zhí)行順序?qū)苤匾撛趺崔k?

Promise 的處理程序(handler)總是會經(jīng)過這個內(nèi)部隊列。

如果有一個包含多個 .then/catch/finally 的鏈,那么它們中的每一個都是異步執(zhí)行的。也就是說,它會首先進(jìn)入隊列。

然后在當(dāng)前代碼執(zhí)行完成并且先前排隊的處理程序(handler)都完成時才會被執(zhí)行。

2. 怎么才能讓 code finished 在 promise done 之后運行呢?

很簡單,只需要像下面這樣使用 .then 將其放入隊列:

 
 
 
 
  1. Promise.resolve() 
  2.   .then(() => alert("promise done!")); //規(guī)定相對應(yīng)的順序 
  3.   .then(() => alert("code finished")); 

上面代碼,加上這語句就是按照預(yù)期執(zhí)行的。

三、未處理的 rejection

現(xiàn)在,可以確切地看到 JavaScript 是如何發(fā)現(xiàn)未處理的 rejection 的。

如果一個 promise 的 error 未被在微*任務(wù)*隊列的末尾進(jìn)行處理,則會出現(xiàn)“未處理的 rejection”。

正常來說。

如果預(yù)期可能會發(fā)生錯誤,會在 promise 鏈上添加 .catch 來處理 error:

 
 
 
 
  1. let promise = Promise.reject(new Error("Promise Failed!")); 
  2. promise.catch(err => alert('caught')); 
  3. // 不會運行:error 已經(jīng)被處理 
  4. window.addEventListener('unhandledrejection', event => alert(event.reason)); 

運行結(jié)果:

但是如果忘記添加 .catch,那么,微任務(wù)隊列清空后,JavaScript 引擎會觸發(fā)下面這事件:

 
 
 
 
  1. let promise = Promise.reject(new Error("Promise Failed!")); 
  2. // Promise Failed! 
  3. window.addEventListener('unhandledrejection', event => alert(event.reason)); 

運行結(jié)果:

如果遲一點再處理這個 error 會怎樣?

例:

 
 
 
 
  1. let promise = Promise.reject(new Error("Promise Failed!")); 
  2. setTimeout(() => promise.catch(err => alert('caught')), 1000); 
  3. // Error: Promise Failed! 
  4. window.addEventListener('unhandledrejection', event => alert(event.reason)); 

現(xiàn)在,如果運行上面這段代碼,會先看到 Promise Failed!,然后才是 caught。

注:

如果并不了解微任務(wù)隊列,可能會想:“為什么 unhandledrejection 處理程序(handler)會運行?已經(jīng)捕獲(catch)并處理了 error!”。

當(dāng)微任務(wù)隊列中的任務(wù)都完成時,才會生成 unhandledrejection:引擎會檢查 promise,如果 promise 中的任意一個出現(xiàn) “rejected” 狀態(tài),unhandledrejection 事件就會被觸發(fā)。

在上面這個例子中,被添加到 setTimeout 中的 .catch 也會被觸發(fā)。只是會在 unhandledrejection 事件出現(xiàn)之后才會被觸發(fā)。

四、總結(jié)

本文基于JavaScript基礎(chǔ),介紹了微任務(wù)。其中.then/catch/finally 處理程序(handler),總是在當(dāng)前代碼完成后才會被調(diào)用。

如果需要確保一段代碼,在 .then/catch/finally 之后被執(zhí)行,可以將它添加到鏈?zhǔn)秸{(diào)用的 .then 中。

在大多數(shù) JavaScript 引擎中(包括瀏覽器和 Node.js),微任務(wù)(microtask)的概念與“事件循環(huán)(event loop)”和“宏任務(wù)(macrotasks)”緊密相關(guān)。

代碼很簡單,希望能夠幫助你更好的學(xué)習(xí)。


文章名稱:一篇文章帶你搞懂JavaScript微任務(wù)(Microtask)
本文路徑:http://www.5511xx.com/article/dpseish.html