摘要:如果你要問他和誰當(dāng)進(jìn)去的快,要從下面兩個(gè)方面考慮結(jié)束時(shí)。至于什么,查了很多的資料,了解到一個(gè)瀏覽器環(huán)境只能有一個(gè)事件循環(huán),而一個(gè)事件循環(huán)可以有多個(gè)任務(wù)隊(duì)列。
====據(jù)說這是今日頭條去年的一道筆試題,主要考察的是setTimeout async promise執(zhí)行順序
~先雙手奉上這道題目~
async function async1() { console.log("async1 start"); await async2(); console.log("async1 end"); } async function async2() { console.log( "async2"); } console.log("script start"); setTimeout(function () { console.log("settimeout"); },0); async1(); new Promise(function (resolve) { console.log("promise1"); resolve(); }).then(function () { console.log("promise2"); }); console.log("script end");
首先,我們先來了解幾個(gè)概念:
JS眾所周知是單線程語言,Javascript引擎同一時(shí)刻只能執(zhí)行一個(gè)代碼塊,使用Event Loop作為它的異步執(zhí)行機(jī)制
那么Event Loop是如何實(shí)現(xiàn)異步呢,個(gè)人淺顯的理解如下:
同步代碼按照上下文的順序放進(jìn)主進(jìn)程中去執(zhí)行
異步函數(shù)放進(jìn)異步隊(duì)列中,等待執(zhí)行,在異步隊(duì)列執(zhí)行的順序按照先進(jìn)先出的原則
等主進(jìn)程中的同步函數(shù)執(zhí)行完畢后,輪詢?nèi)?zhí)行異步隊(duì)列中的異步函數(shù)
??注意: setTimeOut并不是直接的把你的回掉函數(shù)放進(jìn)上述的異步隊(duì)列中去,而是在定時(shí)器的時(shí)間到了之后,把回掉函數(shù)放到執(zhí)行異步隊(duì)列中去。如果此時(shí)這個(gè)隊(duì)列已經(jīng)有很多任務(wù)了,那就排在他們的后面。這也就解釋了為什么setTimeOut為什么不能精準(zhǔn)的執(zhí)行的問題了。setTimeOut執(zhí)行需要滿足兩個(gè)條件:
1. 主進(jìn)程必須是空閑的狀態(tài),如果到時(shí)間了,主進(jìn)程不空閑也不會執(zhí)行你的回掉函數(shù) 2. 這個(gè)回掉函數(shù)需要等到插入異步隊(duì)列時(shí)前面的異步函數(shù)都執(zhí)行完了,才會執(zhí)行
理解了Eventloop異步實(shí)現(xiàn)的方式,再來補(bǔ)充一下promise、async/await
首先,new Promise是同步的任務(wù),會被放到主進(jìn)程中去立即執(zhí)行。而.then()函數(shù)是異步任務(wù)會放到異步隊(duì)列中去,那什么時(shí)候放到異步隊(duì)列中去呢?當(dāng)你的promise狀態(tài)結(jié)束的時(shí)候,就會立即放進(jìn)異步隊(duì)列中去了。如果你要問他和setTimeOut誰當(dāng)進(jìn)去的快,要從下面兩個(gè)方面考慮:
1. promise結(jié)束時(shí)。.then內(nèi)函數(shù)插入異步隊(duì)列的時(shí)間與setTimeOut的回掉函數(shù)插入隊(duì)列的時(shí)間,誰的早,誰的就最快 2. **如果promise是同步的而setTimeOut時(shí)間是0,那么是promise先執(zhí)行**。至于什么,查了很多的資料,了解到:一個(gè)瀏覽器環(huán)境只能有一個(gè)事件循環(huán),而一個(gè)事件循環(huán)可以有多個(gè)任務(wù)隊(duì)列。settimeout所在的隊(duì)列與promise.then()的隊(duì)列不同,面對此種情況,v8實(shí)現(xiàn)的時(shí)候會先從promise.then()的隊(duì)列取任務(wù),但是并沒有很理解,如果有大佬愿意指點(diǎn)迷津,請留言告知
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/99720.html
摘要:下面開始分析開頭的代碼第一輪事件循環(huán)流程整體作為第一個(gè)宏任務(wù)進(jìn)入主線程,遇到,輸出遇到函數(shù)聲明,聲明暫時(shí)不用管遇到,其回調(diào)函數(shù)被分發(fā)到微任務(wù)中。我們記為遇到,其回調(diào)函數(shù)被分發(fā)到宏任務(wù)中。 先上一道常見的筆試題 console.log(1); async function async1() { console.log(2); await async2(); con...
摘要:是這樣描述的函數(shù)中可能會有表達(dá)式,這會使函數(shù)暫停執(zhí)行,等待表達(dá)式中的解析完成后繼續(xù)執(zhí)行函數(shù)并返回解決結(jié)果。返回值返回對象的處理結(jié)果。當(dāng)執(zhí)行到時(shí),這個(gè)任務(wù)會被放入到回調(diào)隊(duì)列中,等待調(diào)用棧有空閑時(shí)事件循環(huán)再來取走它。 原文地址:https://lvdingjin.github.io/tech/2018/05/27/async-and-await.html 故事要從一道今日頭條的筆試題說起...
摘要:下面開始分析開頭的代碼第一輪事件循環(huán)流程整體作為第一個(gè)宏任務(wù)進(jìn)入主線程,遇到,輸出遇到函數(shù)聲明,聲明暫時(shí)不用管遇到,其回調(diào)函數(shù)被分發(fā)到微任務(wù)中。我們記為遇到,其回調(diào)函數(shù)被分發(fā)到宏任務(wù)中。 先上一道常見的筆試題 console.log(1); async function async1() { console.log(2); await async2(); con...
摘要:對象是一個(gè)返回值的代理,這個(gè)返回值在對象創(chuàng)建時(shí)未必已知。這使得異步方法可以像同步方法那樣返回值異步方法會返回一個(gè)包含了原返回值的對象來替代原返回值。 前言 近來參加校招筆試,發(fā)現(xiàn)有好幾道關(guān)于Promise的題目。然而我都沒有了解過。所以,這篇文章以網(wǎng)易筆試的一道題開始,記錄關(guān)于Promise的那些事。文章地址:http://lsxj615.com/2016/08/04... 筆試題 c...
閱讀 3637·2023-04-26 02:05
閱讀 2077·2021-11-19 11:30
閱讀 4313·2021-09-30 09:59
閱讀 3233·2021-09-10 10:51
閱讀 2678·2021-09-01 10:30
閱讀 1593·2021-08-11 11:20
閱讀 2682·2019-08-30 15:54
閱讀 620·2019-08-30 10:49