摘要:版本以及之前,本身還沒有異步執(zhí)行代碼的能力,宿主環(huán)境傳遞給引擎,然后按順序執(zhí)行,由宿主發(fā)起任務(wù)。采納引擎術(shù)語,把宿主發(fā)起的任務(wù)稱為宏觀任務(wù),把引擎發(fā)起的任務(wù)稱為微觀任務(wù)?;居梅ㄊ纠幕卣{(diào)是一個異步的執(zhí)行過程。
筆記說明
重學(xué)前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學(xué)習過程的一些要點筆記以及感悟,完整的可以加入winter的專欄學(xué)習【原文有winter的語音】,如有侵權(quán)請聯(lián)系我,郵箱:[email protected]。一、引言
一個 JavaScript 引擎會常駐于內(nèi)存中,它等待著 宿主 把 JavaScript 代碼或者函數(shù)傳遞給它執(zhí)行。
1、ES3版本以及之前,JavaScript 本身還沒有異步執(zhí)行代碼的能力,宿主環(huán)境傳遞給 JavaScript 引擎,然后按順序執(zhí)行,由宿主發(fā)起任務(wù)。
2、ES5之后,JavaScript 引入了 Promise,不需要瀏覽器的安排,JavaScript 引擎本身也可以發(fā)起任務(wù)。
3、采納JSC引擎術(shù)語,把宿主發(fā)起的任務(wù)稱為宏觀任務(wù),把JavaScript引擎發(fā)起的任務(wù)稱為微觀任務(wù)。
二、宏觀和微觀任務(wù)JavaScript 引擎等待宿主環(huán)境分配宏觀任務(wù),在 Node 術(shù)語中,把這個部分稱為事件循環(huán)。
1、用偽代碼來表示:跑在獨立線程中的循環(huán)
while(TRUE) { r = wait(); execute(r); }
2、整個循環(huán)做的事情基本上就是反復(fù) 等待 - 執(zhí)行,這里的執(zhí)行過程,其實都是一個宏觀任務(wù)??梢源笾吕斫鉃椋汉暧^任務(wù)的隊列就相當于時間循環(huán)。
3、在宏觀任務(wù)中,JavaScript 的 Promise 還會產(chǎn)生異步代碼,JavaScript 必須保證這些異步代碼在一個宏觀任務(wù)中完成,因此,每個宏觀任務(wù)中又包含了一個微觀任務(wù)隊列:如下圖所示
例如:Promise 永遠在隊列尾部添加微觀任務(wù)。setTimeout 等宿主 API,則會添加宏觀任務(wù)。
三、PromiseJavaScript 語言提供的一種標準化的異步管理方式,當進行 io、等待或者其它異步操作的函數(shù),不返回真實結(jié)果,而返回一個承諾,函數(shù)的調(diào)用方可以在合適的時機,選擇等待這個承諾兌現(xiàn)。3.1、基本用法示例
function sleep(duration) { return new Promise(function(resolve, reject) { setTimeout(resolve,duration); }) } sleep(1000).then( ()=> console.log("finished"));
Promise 的 then 回調(diào)是一個異步的執(zhí)行過程。
3.2、Promise 函數(shù)中的執(zhí)行順序var r = new Promise(function(resolve, reject){ console.log("a"); resolve() }); r.then(() => console.log("c")); console.log("b") // 輸出順序:a b c3.3、setTimeout 混用的 Promise
var r = new Promise(function(resolve, reject){ console.log("a"); resolve() }); setTimeout(()=>console.log("d"), 0) r.then(() => console.log("c")); console.log("b") // 輸出順序:a b c d
Promise 產(chǎn)生的是 JavaScript 引擎內(nèi)部的微任務(wù),而 setTimeout 是瀏覽器 API,它產(chǎn)生宏任務(wù)。所以d 必定在 c 之后輸出。
3.4、一個耗時 1 秒的 PromisesetTimeout(()=>console.log("d"), 0) var r = new Promise(function(resolve, reject){ resolve() }); r.then(() => { var begin = Date.now(); while(Date.now() - begin < 1000); console.log("c1") new Promise(function(resolve, reject){ resolve() }).then(() => console.log("c2")) }); // 輸出順序:c1 c2 d
這個例子很好的解釋了微任務(wù)優(yōu)先的原理。
3.5、如何分析異步執(zhí)行的順序1、首先我們分析有多少個宏任務(wù)
2、在每個宏任務(wù)中,分析有多少個微任務(wù)
3、根據(jù)調(diào)用次序,確定宏任務(wù)中的微任務(wù)執(zhí)行次序
4、根據(jù)宏任務(wù)的觸發(fā)規(guī)則和調(diào)用次序,確定宏任務(wù)的執(zhí)行次序
5、確定整個順序
function sleep(duration) { return new Promise(function(resolve, reject) { console.log("b"); setTimeout(resolve,duration); }) } console.log("a"); sleep(5000).then(()=>console.log("c")); // 輸出順序:a b c(c要等5秒)
第一個宏觀任務(wù)中,包含了先后同步執(zhí)行的 console.log("a"); 和 console.log("b");。
setTimeout 后,第二個宏觀任務(wù)執(zhí)行調(diào)用了 resolve,然后 then 中的代碼異步得到執(zhí)行,調(diào)用了 console.log("c")。
四、新特性:async/awaitasync/await 是 ES2016 新加入的特性,它提供了用 for、if 等代碼結(jié)構(gòu)來編寫異步的方式,并且運行時基礎(chǔ)是 Promise。
1、async 函數(shù)是在 function 關(guān)鍵字之前加上 async 關(guān)鍵字,這樣就定義了一個 async 函數(shù),可以在其中使用 await 來等待一個 Promise。
function sleep(duration) { return new Promise(function(resolve, reject) { setTimeout(resolve,duration); }) } async function foo(){ console.log("a") await sleep(2000) console.log("b") } foo(); // 輸出順序:a b(b要等兩秒)
2、async 嵌套
function sleep(duration) { return new Promise(function(resolve, reject) { setTimeout(resolve,duration); }) } async function foo(name){ await sleep(2000) console.log(name) } async function foo2(){ await foo("a"); await foo("b"); } foo2(); // 輸出順序:a(a等兩秒) b(b也等兩秒)個人總結(jié)
看完這篇確實幫我解決了之前困擾我的問題,贊一個。。。明天也要加油鴨。。。。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/55058.html
摘要:版本以及之前,本身還沒有異步執(zhí)行代碼的能力,宿主環(huán)境傳遞給引擎,然后按順序執(zhí)行,由宿主發(fā)起任務(wù)。采納引擎術(shù)語,把宿主發(fā)起的任務(wù)稱為宏觀任務(wù),把引擎發(fā)起的任務(wù)稱為微觀任務(wù)?;居梅ㄊ纠幕卣{(diào)是一個異步的執(zhí)行過程。 筆記說明 重學(xué)前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學(xué)習過程的一些要點筆記以及感悟,完整的...
摘要:版本以及之前,本身還沒有異步執(zhí)行代碼的能力,宿主環(huán)境傳遞給引擎,然后按順序執(zhí)行,由宿主發(fā)起任務(wù)。采納引擎術(shù)語,把宿主發(fā)起的任務(wù)稱為宏觀任務(wù),把引擎發(fā)起的任務(wù)稱為微觀任務(wù)。基本用法示例的回調(diào)是一個異步的執(zhí)行過程。 筆記說明 重學(xué)前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學(xué)習過程的一些要點筆記以及感悟,完整的...
摘要:即使耗時一秒的執(zhí)行完畢,再的,仍然先于執(zhí)行了,這很好地解釋了微任務(wù)優(yōu)先的原理。把整個代碼分割成了個宏觀任務(wù),這里不論是秒還是秒,都是一樣的。 js實現(xiàn)異步的幾種形式 回調(diào)函數(shù) 事件監(jiān)聽 - 事件驅(qū)動模式 發(fā)布/訂閱 - 觀察者模式 Promises對象 js異步歷史 一個 JavaScript 引擎會常駐于內(nèi)存中,它等待著我們把JavaScript 代碼或者函數(shù)傳遞給它執(zhí)行 在 ...
摘要:模板語法四種詞法定義二空白符號空白符號分類或稱是,是縮進符,字符串中寫的。注意換行符會影響的兩個重要語法特性自動插入分號和規(guī)則。 筆記說明 重學(xué)前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學(xué)習過程的一些要點筆記以及感悟,完整的可以加入winter的專欄學(xué)習【原文有winter的語音】,如有侵權(quán)請聯(lián)系我,郵箱...
閱讀 2036·2021-11-08 13:14
閱讀 2944·2021-10-18 13:34
閱讀 2032·2021-09-23 11:21
閱讀 3595·2019-08-30 15:54
閱讀 1763·2019-08-30 15:54
閱讀 2933·2019-08-29 15:33
閱讀 2588·2019-08-29 14:01
閱讀 1949·2019-08-29 13:52