成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

嚼一嚼event loop

wangtdgoodluck / 1540人閱讀

摘要:設(shè)計(jì)為單線程設(shè)計(jì)為單線程還是跟他的用途有關(guān)試想一下如果設(shè)計(jì)為多線程那么同時(shí)修改和刪除同一個(gè)瀏覽器又該如何執(zhí)行需要異步我在執(zhí)行但用戶不知道你好啊上圖例子循環(huán)耗時(shí)會(huì)很久這意味著用戶得不到你好啊的響應(yīng)就會(huì)下意識(shí)會(huì)認(rèn)為瀏覽器卡死了所以必須要有異步通

js設(shè)計(jì)為單線程
js設(shè)計(jì)為單線程還是跟他的用途有關(guān)
試想一下 如果js設(shè)計(jì)為多線程 那么同時(shí)修改和刪除同一個(gè)dom 瀏覽器又該如何執(zhí)行?

js需要異步
for (var i=0;i<9999;i++){
  console.log("我在執(zhí)行 但用戶不知道")
}
console.log("你好啊")
上圖例子 for循環(huán)耗時(shí)會(huì)很久
這意味著 用戶得不到 "你好啊" 的響應(yīng) 就會(huì)下意識(shí)會(huì)認(rèn)為瀏覽器卡死了 所以js必須要有異步
js通過事件循環(huán)來實(shí)現(xiàn)異步 這也是js的運(yùn)行機(jī)制
一方面代碼慢慢跑著 另一方面用戶已經(jīng)抓狂

js事件循環(huán) (說白了不斷執(zhí)行倆步驟) 一、歸類
遇到同步任務(wù)直接執(zhí)行,遇到異步任務(wù)分類為宏任務(wù)(macro-task)微任務(wù)(micro-task)。
宏任務(wù):整體的Script setTimeout setInterval
微任務(wù):Promise process.nextTick

請(qǐng)看示例代碼:

// 這是一個(gè)同步任務(wù)
console.log("1")            --------> 直接被執(zhí)行
                                      目前打印結(jié)果為:1

// 這是一個(gè)宏任務(wù)
setTimeout(function () {    --------> 整體的setTimeout被放進(jìn)宏任務(wù)列表
  console.log("2")                    目前宏任務(wù)列表記為【s2】
});

new Promise(function (resolve) {
  // 這里是同步任務(wù)
  console.log("3");         --------> 直接被執(zhí)行
  resolve();                          目前打印結(jié)果為:1、3
  // then是一個(gè)微任務(wù)
}).then(function () {       --------> 整體的then[包含里面的setTimeout]被放進(jìn)微任務(wù)列表
  console.log("4")                    目前微任務(wù)列表記為【t45】
  setTimeout(function () {
    console.log("5")
  });
});
第一輪小結(jié):
執(zhí)行到這里的結(jié)果:1、3

宏任務(wù)列表如下:
setTimeout(function () {
  console.log("2")
});

微任務(wù)列表如下:
then(function () {
  console.log("4")
  setTimeout(function () {
    console.log("5")
  });
});
二、有微則微,無微則宏
如果微任務(wù)列表里面有任務(wù) 會(huì)執(zhí)行完畢后在執(zhí)行宏任務(wù) (ps:開篇有流程圖)
瀏覽器瞅了一眼微任務(wù)列表 發(fā)現(xiàn)里面有微任務(wù) 就開始全部執(zhí)行
then(function () {
  console.log("4")            --------> 直接被執(zhí)行
                                        目前打印結(jié)果為:1、3、4
  setTimeout(function () {    --------> 被放進(jìn)宏任務(wù)列表了
    console.log("5")                    目前宏任務(wù)列表記為【s2、s5】
  });
});


瀏覽器發(fā)現(xiàn)微任務(wù)執(zhí)行完畢了

開始執(zhí)行宏任務(wù)列表

setTimeout(function () {
  console.log("2")   --------> 直接被執(zhí)行
                               目前打印結(jié)果為:1、3、4、2

});

setTimeout(function () {
  console.log("5")   --------> 直接被執(zhí)行
                               目前打印順序?yàn)椋?1、3、4、2、5、5
});

最終結(jié)果為: 1、3、4、2、5
三、總結(jié) + 實(shí)戰(zhàn)
反復(fù)執(zhí)行以上步驟 就是事件循環(huán)(event loop)
一定要分的清任務(wù)類型 (宏任務(wù) 和 微任務(wù))
  TIP: 為了容易辨別起名為p1(p開頭 里面打印1)
  process.nextTick(function() {         --------> 被放微任務(wù)列表
    console.log("1");                             微任務(wù)列表記為:【p1】
  })

  new Promise(function (resolve) {
    console.log("2");                   --------> 直接執(zhí)行
    resolve();                                    目前打印順序?yàn)椋?
  }).then(function () {                 --------> 整體的then被放進(jìn)微任務(wù)列表[包含其中的setTimeout 4]
    console.log("3");                             微任務(wù)列表記為:【p1 t34】
    setTimeout(function () {
      console.log("4")
    });
  });

  setTimeout(function () {              --------> 被放宏任務(wù)列表
    console.log("5")                              宏任務(wù)列表記為:【s5】
  });

  new Promise(function (resolve) {
    setTimeout(function () {            --------> 被放宏任務(wù)列表
      console.log("6")                            宏任務(wù)列表記為:【s5 s6】
    });
    resolve()
  }).then(function () {                 --------> 整體的then被放進(jìn)微任務(wù)列表[包含其中的setTimeout和其中的多層嵌套]
    setTimeout(function () {                      微任務(wù)列表記為:【p1 t34 t789】
      console.log("7")
      new Promise(function (resolve) {
        setTimeout(function () {
          console.log("8")
        });
        resolve()
      }).then(function () {
        setTimeout(function () {
          console.log("9")
        });
      });
    });
  });
  console.log("10")                      --------> 直接執(zhí)行
                                                   目前打印順序?yàn)椋?、10
第一輪小結(jié):
執(zhí)行結(jié)果為:2、10

宏任務(wù)列表如下:
// s5
setTimeout(function () {
  console.log("5")
});
//s6
setTimeout(function () {
  console.log("6")
});

微任務(wù)列表如下:
// p1
process.nextTick(function() {
  console.log("1");
})
// t34
then(function () {
  console.log("3");
  setTimeout(function () {
    console.log("4")
  });
});
// t789
then(function () {
  setTimeout(function () {
    console.log("7")
    new Promise(function (resolve) {
      setTimeout(function () {
        console.log("8")
      });
      resolve()
    }).then(function () {
      setTimeout(function () {
        console.log("9")
      });
    });
  });
開始執(zhí)行第二輪:
有微任務(wù) 先執(zhí)行微任務(wù)
將微任務(wù)列表代碼塊搬下來
// p1
process.nextTick(function() {             --------> 執(zhí)行p1
  console.log("1");                                 目前打印順序?yàn)椋?、10、1
})
// t34
then(function () {
  console.log("3");                       --------> 直接執(zhí)行
                                                    目前打印順序?yàn)椋?、10、1、3
  setTimeout(function () {                --------> 被放宏任務(wù)列表
    console.log("4")                                宏任務(wù)列表記為:【s5 s6 s4】
  });
});
// t789
then(function () {
  setTimeout(function () {              --------> 被放宏任務(wù)列表
    console.log("7")                              宏任務(wù)列表記為:【s5 s6 s4 s789】
    new Promise(function (resolve) {
      setTimeout(function () {
        console.log("8")
      });
      resolve()
    }).then(function () {
      setTimeout(function () {
        console.log("9")
      });
    });
  });
})

微任務(wù)執(zhí)行完畢了 該執(zhí)行我們的宏任務(wù)列表了
因?yàn)槲⑷蝿?wù)里面包含一部分宏任務(wù)
所以現(xiàn)在的宏任務(wù)列表已經(jīng)增加了
現(xiàn)在把當(dāng)前的宏任務(wù)列表搬下來
//s5
setTimeout(function () {           --------> 執(zhí)行s5
  console.log("5")                           目前打印順序?yàn)椋?、10、1、3、5
});
//s6
setTimeout(function () {           --------> 執(zhí)行s6
  console.log("6")                           目前打印順序?yàn)椋?、10、1、3、5、6
});
//s4
setTimeout(function () {           --------> 執(zhí)行s4
  console.log("4")                           目前打印順序?yàn)椋?、10、1、3、5、6、4
});
// s789
setTimeout(function () {           --------> 執(zhí)行s789
  console.log("7")                           目前打印順序?yàn)椋?、10、1、3、5、6、4、7
  new Promise(function (resolve) {
    setTimeout(function () {       --------> 被放宏任務(wù)列表
      console.log("8")                       宏任務(wù)列表記為:【s8】
    });
    resolve()
  }).then(function () {            --------> 整體的then被放微任務(wù)列表[包含里面的setTimeout]
    setTimeout(function () {                 微任務(wù)列表記為:【t9】
      console.log("9")
    });
  });
});
再次小結(jié):
當(dāng)前結(jié)果:2、10、1、3、5、6、4、7
馬上就要執(zhí)行完了心里萬分激動(dòng)啊 ( 瀏覽器的內(nèi)心獨(dú)白 ^▽^  ...)
宏任務(wù)列表如下:
// s8
setTimeout(function () {
  console.log("8")
});

微任務(wù)列表如下:
// t9
then(function () {
  setTimeout(function () {
    console.log("9")
  });
});


繼續(xù)執(zhí)行 依舊遵循有微則微 無微則宏
瀏覽器發(fā)現(xiàn)有一條微任務(wù)
那就開始執(zhí)行吧~
//t9
then(function () {
  setTimeout(function () {   --------> 執(zhí)行t9 把里面的setTimeout放入宏任務(wù)列表
    console.log("9")                   宏任務(wù)列表記為:【s8 s9】
  });
});

微任務(wù)列表執(zhí)行完畢
開始執(zhí)行宏任務(wù)(宏任務(wù)剛剛又有新增哦~[s9])
// s8
setTimeout(function () {     --------> 執(zhí)行s8
  console.log("8")                     目前打印順序?yàn)椋?、10、1、3、5、6、4、7、8
});
// s9
setTimeout(function () {     --------> 執(zhí)行s9
  console.log("9")                     目前打印順序?yàn)椋?、10、1、3、5、6、4、7、8、9
});

到這里 微任務(wù)列表 和 宏任務(wù)列表均為空 就執(zhí)行完畢了

再此留下一道沒有答案的題供練手

  new Promise(function (resolve) {
    console.log("1");
    resolve();
  }).then(function () {
    setTimeout(function () {
      console.log("2")
    });
  });

  setTimeout(function () {
    console.log("3")
    process.nextTick(function() {
      console.log("4");
    })
    process.nextTick(function() {
      console.log("5");
    })
  });

  new Promise(function (resolve) {
    console.log("6");
    resolve();
    setTimeout(function () {
      console.log("7")
      new Promise(function (resolve) {
        console.log("8");
        resolve();
      }).then(function () {
        setTimeout(function () {
          console.log("9")
        });
      });
    });

  }).then(function () {

    setTimeout(function () {
      console.log("10")
    });

    new Promise(function (resolve) {
      console.log("11");
      resolve();
    }).then(function () {
      setTimeout(function () {
        console.log("12")
      });
    });
  });
本人學(xué)識(shí)有限 文章多有不足
若有錯(cuò)誤 請(qǐng)大方指出 以免誤導(dǎo)他人

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104037.html

相關(guān)文章

  • event loop規(guī)范探究javaScript異步及瀏覽器更新渲染時(shí)機(jī)

    摘要:規(guī)范中定義了瀏覽器何時(shí)進(jìn)行渲染更新,了解它有助于性能優(yōu)化。結(jié)合一些資料,對(duì)上邊規(guī)范給出一些理解有誤請(qǐng)指正每個(gè)線程都有自己的。列為,列為,列為。我們都知道是單線程,渲染計(jì)算和腳本運(yùn)行共用同一線程網(wǎng)絡(luò)請(qǐng)求會(huì)有其他線程,導(dǎo)致腳本運(yùn)行會(huì)阻塞渲染。 本文轉(zhuǎn)自blog 轉(zhuǎn)載請(qǐng)注明出處 異步的思考 event loops隱藏得比較深,很多人對(duì)它很陌生。但提起異步,相信每個(gè)人都知道。異步背后的靠山就是...

    13651657101 評(píng)論0 收藏0
  • 我不該動(dòng)你的,Event Loops(深坑)

    摘要:我不該動(dòng)你的,寫在前面的話本意是想好好研究下,看了幾篇博客后,才意識(shí)到作為前端打字員的我有多無知,這坑忒深了。這樣的話,如果是第一種解釋,應(yīng)該在運(yùn)行之前,頁面就變成了紅色否則就應(yīng)該采取第二種解釋。 我不該動(dòng)你的,Event Loops 寫在前面的話 本意是想好好研究下 Event Loops, 看了幾篇博客后,才意識(shí)到作為前端打字員的我有多無知,這坑忒深了。 macrotask?,mi...

    wenhai.he 評(píng)論0 收藏0
  • event loop 與 vue

    摘要:但是導(dǎo)致了很明顯的性能問題。上述兩個(gè)例子其實(shí)是在這個(gè)中找到的,第一個(gè)使用的版本是,這個(gè)版本的實(shí)現(xiàn)是采用了,而后因?yàn)榈睦锏挠?,于是尤雨溪更改了?shí)現(xiàn),換成了,也就是后一個(gè)所使用的。后來尤雨溪了解到是將回調(diào)放入的隊(duì)列。 結(jié)論 對(duì)于event loop 可以抽象成一段簡(jiǎn)單的代碼表示 for (macroTask of macroTaskQueue) { // 1. Handle cur...

    springDevBird 評(píng)論0 收藏0
  • event loop 與 vue

    摘要:但是導(dǎo)致了很明顯的性能問題。上述兩個(gè)例子其實(shí)是在這個(gè)中找到的,第一個(gè)使用的版本是,這個(gè)版本的實(shí)現(xiàn)是采用了,而后因?yàn)榈睦锏挠?,于是尤雨溪更改了?shí)現(xiàn),換成了,也就是后一個(gè)所使用的。后來尤雨溪了解到是將回調(diào)放入的隊(duì)列。 結(jié)論 對(duì)于event loop 可以抽象成一段簡(jiǎn)單的代碼表示 for (macroTask of macroTaskQueue) { // 1. Handle cur...

    Barry_Ng 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<