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

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
前端開(kāi)發(fā)JS:事件循環(huán)機(jī)制、調(diào)用棧以及任務(wù)隊(duì)列

js里的事件循環(huán)機(jī)制十分有趣。從很多面試題也可以看出來(lái),考察簡(jiǎn)單的setTimeout也就是考察這個(gè)機(jī)制的。

創(chuàng)新互聯(lián)建站主要為客戶提供服務(wù)項(xiàng)目涵蓋了網(wǎng)頁(yè)視覺(jué)設(shè)計(jì)、VI標(biāo)志設(shè)計(jì)、成都營(yíng)銷(xiāo)網(wǎng)站建設(shè)、網(wǎng)站程序開(kāi)發(fā)、HTML5響應(yīng)式網(wǎng)站建設(shè)公司、移動(dòng)網(wǎng)站建設(shè)、微商城、網(wǎng)站托管及網(wǎng)站維護(hù)、WEB系統(tǒng)開(kāi)發(fā)、域名注冊(cè)、國(guó)內(nèi)外服務(wù)器租用、視頻、平面設(shè)計(jì)、SEO優(yōu)化排名。設(shè)計(jì)、前端、后端三個(gè)建站步驟的完善服務(wù)體系。一人跟蹤測(cè)試的建站服務(wù)標(biāo)準(zhǔn)。已經(jīng)為航空箱行業(yè)客戶提供了網(wǎng)站設(shè)計(jì)服務(wù)。

在之前,我只是簡(jiǎn)單地認(rèn)為由于函數(shù)執(zhí)行很快,setTimeout執(zhí)行時(shí)間即便為0也不會(huì)馬上輸出,而是等待函數(shù)執(zhí)行完后再輸出。這只對(duì)了一半。

實(shí)際上其運(yùn)行機(jī)制就是js中的事件循環(huán)機(jī)制,在這個(gè)循環(huán)機(jī)制中呢,又與call Stack和task queue有關(guān)。

一、js事件循環(huán)機(jī)制

事件循環(huán)機(jī)制呢,簡(jiǎn)單點(diǎn)來(lái)說(shuō),就是在執(zhí)行上下文的過(guò)程中,對(duì)函數(shù)的入棧和出棧。執(zhí)行前函數(shù)先入棧,執(zhí)行完后函數(shù)出棧。如若遇到了一些異步操作像回調(diào)函數(shù)以及ajax、setTimeout等,會(huì)先將他們交給瀏覽器的其他模塊去執(zhí)行,執(zhí)行完后,會(huì)把回調(diào)函數(shù)放入到taskqueue中。當(dāng)所有的call stack執(zhí)行完后再開(kāi)始執(zhí)行task queue中的函數(shù)。

舉一個(gè)簡(jiǎn)單的例子:

 
 
 
 
  1. console.log(1);  
  2. setTimeout(function() 

我們來(lái)看一下執(zhí)行的內(nèi)部過(guò)程

1. 執(zhí)行***句,放入call stack中,輸出 1

2. ***句出棧,執(zhí)行第二句,由于是異步執(zhí)行,交給其他模塊。

3. 執(zhí)行完后,將回調(diào)函數(shù)放入taskqueue中

4. 執(zhí)行下一句,同***步一樣,將語(yǔ)句入棧并執(zhí)行,輸出3

5. 語(yǔ)句出棧,此時(shí)call stack空了。開(kāi)始執(zhí)行task queue任務(wù),輸出2

所以,輸出結(jié)果是

與預(yù)想一致。

二、進(jìn)階

如果添加了Promise又如何工作呢?

我們知道,Promise的回調(diào)函數(shù)不是傳入的,而是使用then來(lái)調(diào)用的。因此,Promise中定義的函數(shù)應(yīng)該是馬上執(zhí)行的,then才是其回調(diào)函數(shù),放入queue隊(duì)列中。

還提到了一個(gè)重要的概念:

  • macro-task包括:script(整體代碼), setTimeout, setInterval, setImmediate, I/O, UI rendering。
  • micro-task包括:process.nextTick, Promises, Object.observe, MutationObserver

執(zhí)行順序:函數(shù)調(diào)用棧清空只剩全局執(zhí)行上下文,然后開(kāi)始執(zhí)行所有的micro-task。當(dāng)所有可執(zhí)行的micro-task執(zhí)行完畢之后。循環(huán)再次執(zhí)行macro-task中的一個(gè)任務(wù)隊(duì)列,執(zhí)行完之后再執(zhí)行所有的micro-task,就這樣一直循環(huán)。

 
 
 
 
  1. (function test() {  
  2.     setTimeout(function() {console.log(4)}, 0);  
  3.     new Promise(function executor(resolve) {  
  4.         console.log(1);  
  5.         for( var i=0 ; i<10000 ; i++ ) {  
  6.             i == 9999 && resolve();  
  7.         }  
  8.         console.log(2);  
  9.     }).then(function() {  
  10.         console.log(5);  
  11.     });  
  12.     console.log(3);})() 

執(zhí)行過(guò)程:

1. 遇到setTimeout,交給其他模塊執(zhí)行,執(zhí)行完后回調(diào)放入macro-task中

2. 遇到Promise,立即執(zhí)行里面的function,輸出1。

3. 循環(huán)開(kāi)始,遇到resolve(),修改Promise狀態(tài)為fulfill。繼續(xù)執(zhí)行,輸出2。

4. 遇到then,將回調(diào)放入micro-task中。

5. 繼續(xù)執(zhí)行,輸出3。

6. call stack執(zhí)行完畢了。開(kāi)始執(zhí)行micro-task中的回調(diào)函數(shù),輸出5。

7. micro-task執(zhí)行完畢,開(kāi)始執(zhí)行macro-task中的回調(diào)函數(shù),輸出4。

8. 結(jié)束。

【本文為專欄作者“謝軍”的原創(chuàng)稿件,轉(zhuǎn)載可通過(guò)作者微信公眾號(hào)(jingfeng18)獲取聯(lián)系】


標(biāo)題名稱:前端開(kāi)發(fā)JS:事件循環(huán)機(jī)制、調(diào)用棧以及任務(wù)隊(duì)列
文章分享:http://m.5511xx.com/article/dhohpsj.html