日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

定时器和promise_从Promise链理解EventLoop

發布時間:2025/3/8 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 定时器和promise_从Promise链理解EventLoop 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

面試題

new Promise(resolve => { setTimeout(()=>{ console.log(666); new Promise(resolve => { resolve(); }) .then(() => {console.log(777);}) }) resolve(); }) .then(() => { new Promise(resolve => { resolve(); }) .then(() => {console.log(111);}) .then(() => {console.log(222);}); }) .then(() => { new Promise((resolve) => { resolve() }) .then(() => { new Promise((resolve) => { resolve() }) .then(() => {console.log(444)}) }) .then(() => { console.log(555); })}).then(() => { console.log(333);})

答案

111222333444555666777

如果你沒有得出正確的結果,有必要繼續往下看.

為了能正確解答上題,需要對宏任務、微任務以及Event-Loop深入理解.

知識點

宏任務

瀏覽器執行代碼的過程中,JS引擎會將大部分代碼進行分類,分別分到這兩個隊列中--宏任務(macrotask ) 和 微任務(microtask ) .

常見的宏任務:script(整體代碼), XHR回調,setTimeout, setInterval, setImmediate(node獨有), I/O.

上面的描述仍然有些生澀,下面借助案例深入理解.

app.js

setTimeout(()=>{ //宏任務2 console.log(2); },0) setTimeout(()=>{ //宏任務3 console.log(3); },0) console.log(1);

執行結果: 1 -- 2 -- 3

?瀏覽器開始運行 app.js 時啟動了第一個宏任務(宏任務1,指向app.js整體代碼)并開始執行.?在執行宏任務1途中遇到了第一個定時器,瀏覽器便會開啟一個新的宏任務2,定時器被添加到宏任務隊列等待,線程繼續往下執行.?隨后又遇到了定時器開啟一個新的宏任務3,定時器又被添加到宏任務隊列等待,宏任務3排在宏任務2的后面,線程繼續往下執行.?線程走到最后輸出了1,此時宏任務1就結束了.瀏覽器此刻就會去宏任務隊列中尋找,排在最前面的是宏任務2,發現延遲時間已到允許執行便輸出了2,宏任務2結束又執行宏任務3輸出3.

宏任務通常是由宿主環境開啟.比如在客戶端,瀏覽器就是宿主環境.開始執行一個腳本文件,開啟一個定時器任務以及ajax請求,都是瀏覽器在其底層完成,并非是通過js 引擎去做的這些工作.在服務器端,node就作為了宿主環境.

微任務

微任務是宏任務的組成部分,微任務與宏任務是包含關系,并非前后并列.如果要談微任務,需要指出它屬于哪個宏任務才有意義.

常見的宏任務:process.nextTick(nodejs端),Promise等.

app.js

console.log(1); new Promise((resolve)=>{ resolve(); }).then(()=>{ console.log(2) }) console.log(3)

執行結果: 1 -- 3 -- 2

?運行 app.js 腳本文件啟動宏任務1,第一行代碼執行輸出1.?碰到Promise,將then的回調函數放入宏任務1的微任務隊列中等待,線程繼續往下.?代碼跑到最后一行輸出3.此時同步代碼執行完畢,開始檢查當前宏任務中的微任務隊列.?運行微任務隊列中的第一個then回調函數輸出2.再檢查微任務隊列,沒有發現其他任務.?微任務隊列執行完畢,宏任務1執行完畢.

宏任務由宿主環境開啟,與此相對應,微任務是 js 引擎從代碼層面開啟的.

如果還對宏任務和微任務的關系模棱兩可,下面從 Event-Loop 角度詳細闡述.

Event-Loop

Event-Loop

從上圖可知,宏任務形成了一個擁有先后順序的隊列.每個宏任務中分為同步代碼和微任務隊列.

?假設js當前的線程執行宏任務1,先執行宏任務1中的同步代碼.?如果碰到Promise或者process.nextTick,就把它們的回調放入當前宏任務1的微任務隊列中.?如果碰到setTimeout, setInterval之類就會在當前宏任務1的隊列后面開啟新的宏任務將回調放入其中.?同步代碼執行完,開始執行宏任務1的微任務隊列,直到微任務隊列的所有任務都執行完.?微任務隊列的所有任務執行完畢,宏任務1再看沒有其他代碼了,當前的事件循環結束.js線程開始執行下一個宏任務,直到所有宏任務執行完畢.如此整體便構成了事件循環機制.

延伸

dom操作屬于宏任務還是微任務

console.log(1); document.getElementById("div").style.color = "red"; console.log(2);

在實踐中發現,當上面代碼執行到第三行時,控制臺輸出了1并且頁面已經完成了重繪,div的顏色變成了紅色.

dom操作它既不是宏任務也不是微任務,它應該歸于同步執行的范疇.

requestAnimationFrame屬于宏任務還是微任務

setTimeout(() => { console.log("11111")}, 0)requestAnimationFrame(() => { console.log("22222")})new Promise(resolve => { console.log('promise'); resolve();}).then(() => {console.log('then')})

執行結果: promise -- then -- 22222 -- 11111

很多人會把 requestAnimationFrame 歸結到宏任務中,因為發現它會在微任務隊列完成后執行.

但實際上 requestAnimationFrame 它既不能算宏任務,也并非是微任務.它的執行時機是在當前宏任務范圍內,執行完同步代碼和微任務隊列后再執行.它仍然屬于宏任務范圍內,但是是在微任務隊列執行完畢后才執行.

Promise的運行機制

包裹函數是同步代碼

new Promise((resolve)=>{ console.log(1); resolve(); }).then(()=>{ console.log(2); })

new Promise里面的包裹的函數,也就是輸出1的那段代碼是同步執行的.而then包裹的函數才會被加載到微任務隊列中等待執行.

Promise鏈條如果沒有return

new Promise((resolve)=>{ console.log(1) resolve();}).then(()=>{ console.log(2);}).then(()=>{ console.log(3);}).then(()=>{ console.log(4);})

執行結果: 1 -- 2 -- 3 -- 4

在平時開發中,在Promise鏈中通常會返回一個新的Promise做異步操作返回相應的值.如下.

new Promise((resolve)=>{ console.log(1) resolve();}).then(()=>{ return new Promise((resolve)=>{ resolve(2) })}).then((n)=>{ console.log(n);})

執行結果: 1 -- 2

但上述代碼中,then函數的回調里沒有返回任何東西.但是后續then包含的回調函數仍然會依次執行,返回 1 -- 2 -- 3 -- 4.并且它可以在末尾無限接then函數,這些函數也都會依次執行.

多個then函數執行次序

new Promise((resolve)=>{ // 1 console.log("a") // 2 resolve(); // 3}).then(()=>{ // 4 console.log("b"); // 5}).then(()=>{ // 6 console.log("c"); // 7}) // 8console.log("d") // 9

執行結果: a -- d -- b -- c

?1,2,3行為同步執行的代碼,一氣呵成輸出 a.?此時線程走到第4行碰到then函數的回調,將其放入微任務的隊列等待.?線程繼續往后走直接跳到了第9行輸出了 d,為什么會忽略第6行的then直接跳到第9行呢?因為第4行的then函數回調執行完畢后才會開始執行第6行的代碼.(如果不理解為什么此刻會忽略掉第6行代碼可以查閱一下函數柯里化的概念).?同步代碼執行完畢,開始執行微任務隊列.此時微任務隊列里面只包含了一個then的回調函數,執行輸出b.?4,5行執行完畢后,開始執行第6行代碼.發現了then函數回調,將其放入微任務隊列中.此時第一個微任務執行完了,將其清空.?微任務隊列中還有一個剛放進去的微任務,執行輸出 c.清除此微任務,至此微任務隊列為空,全部任務執行完畢.

解題

有了以上知識的儲備再回到本文最初的面試題,這道題就可以輕松解決了.(為了方便闡述,加入右邊行號)

new Promise(resolve => { // 1 setTimeout(()=>{ // 2 console.log(666); // 3 new Promise(resolve => { // 4 resolve(); }) .then(() => {console.log(777);}) // 7 }) resolve(); // 9 }) // 10 .then(() => { // 11 new Promise(resolve => { // 12 resolve(); // 13 }) .then(() => {console.log(111);}) // 15 .then(() => {console.log(222);}); // 16 }) // 17 .then(() => { // 18 new Promise((resolve) => { // 19 resolve() }) .then(() => { // 22 new Promise((resolve) => { // 23 resolve() }) .then(() => {console.log(444)}) // 26 }) .then(() => { // 28 console.log(555); // 29 })}).then(() => { // 32 console.log(333);})

?線程執行第一行代碼,同步執行Promise包裹的函數.?在第二行發現定時器,啟動一個宏任務,將定時器的回調放入宏任務隊列等待,線程直接跳到第9行執行?第9行執行完開始執行第11行代碼發現then函數,放入當前微任務隊列中.線程往后再沒有可以執行的代碼了,于是開始執行微任務隊列.?執行微任務隊列進入第12行代碼,運行到第15行代碼時發現then函數放入微任務隊列等待.隨后線程直接跳到第18行,碰到then函數放到微隊列中.后續沒有可執行的代碼了,再開始執行微任務隊列的第一個任務也就是第15行代碼輸出111.?15行執行完執行到16行碰到then回調放入微任務隊列等待.隨后線程跳到18行的微任務開始執行,一直執行到22行碰到then函數又放入微任務隊列等待.此時線程繼續往下跳到第32行碰到then函數放入微任務隊列等待.后續沒有可執行的代碼了,再開始執行微任務隊列的第一個任務.?線程跳到第16行執行微任務輸出 222,隨后又跳到22行執行下一個微任務,在26行處碰到then函數放入微任務隊列等待.線程繼續執行下一個微任務跳到32行輸出 333.至此這一輪的三個微任務全部執行完畢清空,又開始執行微任務隊列的第一個任務,線程跳到第26行輸出 444.?線程執行到28行碰到then函數回調放入微任務隊列等待.后續沒有可執行的代碼了,再開始執行微任務隊列的第一個任務即29行代碼輸出 555.?所有微任務執行完畢,當前宏任務結束.線程開始執行下一個宏任務,線程跳到第三行輸出 666.?線程繼續往后第7行碰到then回調放入微任務隊列,后續沒有可執行的代碼了,再開始執行微任務隊列的第一個任務輸出 777.第二個宏任務執行完畢.

綜上所述:輸出分別為 111 -- 222 -- 333 -- 444 -- 555 -- 666 -- 777

總結

以上是生活随笔為你收集整理的定时器和promise_从Promise链理解EventLoop的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 黄色片免费在线 | 99精品久久| 国产又爽又黄无码无遮挡在线观看 | 欧美看片 | 国产小视频在线观看免费 | 在线观看黄色免费网站 | 在线免费观看成年人视频 | 永久久久久久 | 精品免费在线观看 | av男人网| 91麻豆精品国产91久久久无需广告 | 国产淫语| 久久国产网 | 一区二区三区免费在线观看 | 黄色片99 | 先锋av资源网站 | 台湾性dvd性色av | 又黄又骚又爽 | 能在线看的av| 免费国产在线观看 | 日本亚洲精品 | 女人脱了内裤趴开腿让男躁 | 久久久久女教师免费一区 | av免费福利| 亚洲国产成人精品视频 | 国产一区一区 | 亚洲免费中文 | 国产αv| 美女一区二区三区四区 | 五月天激情视频在线观看 | 在线观看久| 男女激情大尺度做爰视频 | 91久久色 | 亚洲啪av永久无码精品放毛片 | 日本一二三区不卡 | 国产精品丝袜黑色高跟鞋的设计特点 | 日本va在线观看 | 台湾佬美性中文娱乐 | 夫妻露脸自拍[30p] | 日本在线 | 爱吃波客今天最新视频 | 亚洲综合网在线 | 日本做爰三级床戏 | 99国产在线观看 | 久久久久久久网站 | 天天躁狠狠躁狠狠躁夜夜躁68 | 欧美少妇xx| 欧美性videos高清精品 | 国产免费黄色大片 | 国产日韩一区二区在线观看 | 亚洲精品免费av | 91福利视频网站 | 九热视频在线观看 | 超碰人人做 | 亚洲红桃视频 | 亚洲二区中文字幕 | 成人免费毛片视频 | 91久久综合精品国产丝袜蜜芽 | 在线免费a视频 | 五月天综合在线 | 一级啪啪片 | 久久影视中文字幕 | 成人免费三级 | 日韩激情综合网 | 污片免费在线观看 | 你懂的在线观看网站 | 欧美色欧美色 | 免费看国产片在线观看 | 精品久久香蕉国产线看观看亚洲 | 老地方在线观看免费动漫 | 国产精品一区二区在线看 | 性史性农村dvd毛片 日韩精品在线视频观看 | 日日插夜夜爽 | 草草在线影院 | 天天想你在线观看完整版电影免费 | 日本综合色 | 欧美日韩成人一区 | 亚洲国产私拍精品国模在线观看 | 日日夜夜免费精品视频 | 日韩欧美在线一区二区 | 国产成人精品二区三区亚瑟 | 欧美日韩在线播放三区四区 | 香蕉网在线视频 | 在线观看视频国产 | 国产综合在线观看视频 | 爱情岛av永久入口 | 无码人妻丰满熟妇区毛片蜜桃精品 | 色老头一区二区三区 | 日韩精品在线免费观看视频 | 狠狠夜夜 | 二三区视频 | 婷婷激情六月 | 给我免费观看片在线电影的 | 欧美激情一区二区三区蜜桃视频 | 99爱国产 | 少妇人妻偷人精品无码视频新浪 | 五月天婷婷在线观看 | 伊人中文字幕在线观看 | 欧美顶级metart裸体全部自慰 |