国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

從setTimeout看js函數執行過程

2024-05-06 15:23:29
字體:
來源:轉載
供稿:網友

老實說,寫這篇文章的時候心里是有點壓抑的,因為受到打擊了,為什么?就 因為喜歡折騰不小心看到了這個"簡單"的函數:

for (var i = 0; i < 5; i++) {      setTimeout(function () {        console.log(i)      }, i * 1000);    }    console.log(i);

什么?這不就是我很久之前看到的先打印一個5,再打印一個5,之后每隔一秒就打印一個5,直到打印完6個5的實現方法嗎?那么問題來了,如果我要依次打印0,1,2,3,4,5的話我該怎么辦,其實在這之前我就知道有這兩個方法:一個是這樣:

function log(i){setTimeout(function(){console.log(i)},i*1000)};for (var i = 0; i < 5; i++) {      log(i) ;    }    console.log(i);

   還有一個是這樣:

for(var i=0;i<5;i++){(function(e){setTimeout(function(){console.log(e)},i*1000);})(i);};console.log(i);

不怕笑話,在這之前我是沒搞懂這兩個函數真正意義上的作用是用來干嘛的,只強迫自己這樣記住這樣修改就可以了,但是現在不行啊,我有強迫癥啊!于是,我慢慢分析了一下,發現上面那段代碼可以分離成這樣:

i=0時;滿足條件;

setTimeout(function(){console.log(i)},0*1000);

i=1時;滿足條件;

setTimeout(function(){console.log(i)},1*1000);

i=2時;滿足條件;

setTimeout(function(){console.log(i)},2*1000);

i=3時;滿足條件;

setTimeout(function(){console.log(i)},3*1000);

i=4時;滿足條件;

setTimeout(function(){console.log(i)},4*1000);

i=5時,不滿足條件,跳出循環,接著執行for循環后面的console.log(i),打印5;最后依次每秒打印5;

真有意思,為什么setTimeout里面的console.log會是后于for循環外面的console.log執行呢?直到我認識到了這個單詞=>"隊列", 隊列又有宏任務隊列(Macro Task)以及微任務隊列(Micro Task)之分 ,在javascript中:

macro-task包括:script(整體代碼), setTimeout , setInterval, setImmediate, I/O, UI rendering。

micro-task包括:process.nextTick, Promises , Object.observe, MutationObserver

上面函數的setTimeout就屬于宏任務

在js中,事件循環的順序是從script開始第一次循環,隨后全局上下文進入函數調用棧,碰到macro-task就將其交給處理它的模塊處理完之后將回調函數放進macro-task的隊列之中,碰到micro-task也是將其回調函數放進micro-task的隊列之中。直到函數調用棧清空只剩全局執行上下文,然后開始執行所有的micro-task。 當所有可執行的micro-task執行完畢之后。循環再次執行macro-task中的一個任務隊列 ,執行完之后再執行所有的micro-task,就這樣一直循環。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 平阴县| 曲沃县| 大新县| 乌恰县| 镇雄县| 鸡泽县| 陆川县| 祥云县| 无极县| 临朐县| 琼结县| 申扎县| 肃南| 尖扎县| 温泉县| 新津县| 台州市| 东港市| 五家渠市| 渝中区| 嫩江县| 民勤县| 安庆市| 盐边县| 贡觉县| 沙湾县| 伊宁县| 正安县| 禹城市| 庐江县| 伊宁市| 泽州县| 庆阳市| 资阳市| 金平| 化州市| 锡林浩特市| 启东市| 永福县| 吉林省| 河源市|