欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

實例分析js事件循環(huán)機制

 更新時間:2017年12月13日 08:45:33   投稿:laozhang  
這篇文章主要介紹了js事件循環(huán)機制,并通過實例分析了用法和技巧,一起學(xué)習(xí)分享下。

本文通過實例給大家詳細(xì)分析了JS中事件循環(huán)機制的原理和用法,以下是全部內(nèi)容:

var start = new Date()
setTimeout(function () {
 var end = new Date
 console.log('Time elapsed:', end - start, 'ms')
}, 500)
while (new Date() - start < 1000) {
}

有其他語言能完成預(yù)期的功能嗎?Java, 在Java.util.Timer中,對于定時任務(wù)的解決方案是通過多線程手段實現(xiàn)的,任務(wù)對象存儲在任務(wù)隊列,由專門的調(diào)度線程,在新的子線程中完成任務(wù)的執(zhí)行

js是單線程的

JavaScript的主要用途是與用戶互動,以及操作DOM。這決定了它只能是單線程,否則會帶來很復(fù)雜的同步問題。

為了利用多核CPU的計算能力,HTML5提出Web Worker標(biāo)準(zhǔn),允許JavaScript腳本創(chuàng)建多個線程,但是子線程完全受主線程控制,且不得操作DOM。所以,這個新標(biāo)準(zhǔn)并沒有改變JavaScript單線程的本質(zhì)。

函數(shù)調(diào)用棧和任務(wù)隊列

調(diào)用棧

JS執(zhí)行時會形成調(diào)用棧,調(diào)用一個函數(shù)時,返回地址、參數(shù)、本地變量都會被推入棧中,如果當(dāng)前正在運行的函數(shù)中調(diào)用另外一個函數(shù),則該函數(shù)相關(guān)內(nèi)容也會被推入棧頂.該函數(shù)執(zhí)行完畢,則會被彈出調(diào)用棧.變量也隨之彈出,由于復(fù)雜類型值存放于堆中,因此彈出的只是指針,他們的值依然在堆中,由GC決定回收.

事件循環(huán)(event loop) & 任務(wù)隊列(task queue)

JavaScript 主線程擁有一個執(zhí)行棧以及一個任務(wù)隊列

遇到異步操作(例如:setTimeout, AJAX)時,異步操作會由瀏覽器(OS)執(zhí)行,瀏覽器會在這些任務(wù)完成后,將事先定義的回調(diào)函數(shù)推入主線程的任務(wù)隊列(task queue)中,當(dāng)主線程的執(zhí)行棧清空之后會讀取task queue中的回調(diào)函數(shù),當(dāng)task queue被讀取完畢之后,主線程接著執(zhí)行,從而進入一個無限的循環(huán),這就是事件循環(huán).

主線程執(zhí)行棧 & 任務(wù)隊列 循環(huán)執(zhí)行,構(gòu)成事件循環(huán)

結(jié)論

setTimeout()只是將事件插入了"任務(wù)隊列",必須等到當(dāng)前代碼(執(zhí)行棧)執(zhí)行完,主線程才會去執(zhí)行它指定的回調(diào)函數(shù)。要是當(dāng)前代碼耗時很長,有可能要等很久,所以并沒有辦法保證,回調(diào)函數(shù)一定會在setTimeout()指定的時間執(zhí)行。

另一個例子

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

Macrotask & Microtask

macrotask 和 microtask 是異步任務(wù)的兩種分類。在掛起任務(wù)時,JS 引擎會將所有任務(wù)按照類別分到這兩個隊列中,首先在 macrotask 的隊列(這個隊列也被叫做 task queue)中取出第一個任務(wù),執(zhí)行完畢后取出 microtask 隊列中的所有任務(wù)順序執(zhí)行;之后再取 macrotask 任務(wù),周而復(fù)始,直至兩個隊列的任務(wù)都取完。

macro-task: script(整體代碼), setTimeout, setInterval, setImmediate, I/O, UI rendering
micro-task: process.nextTick, Promises(這里指瀏覽器實現(xiàn)的原生 Promise), Object.observe, MutationObserver

結(jié)論

全部代碼(script) macrotask -> microtask queue (含有promise.then) -> macrotask(setTimeout) -> 下一個microtask

Node.js的事件循環(huán)

process.nextTick & setImmediate

process.nextTick指定的任務(wù)總是發(fā)生在所有異步任務(wù)之前

setImmediate指定的任務(wù)總是在下一次Event Loop時執(zhí)行

process.nextTick(function A() {
 console.log(1);
 process.nextTick(function B(){console.log(2);});
});
setTimeout(function timeout() {
 console.log('TIMEOUT FIRED');
}, 0)
new Promise(function(resolve) {
 console.log('glob1_promise');
 resolve();
}).then(function() {
 console.log('glob1_then')
})
process.nextTick(function() {
 console.log('glob1_nextTick');
})

相關(guān)文章

  • JS highcharts動態(tài)柱狀圖原理及實現(xiàn)

    JS highcharts動態(tài)柱狀圖原理及實現(xiàn)

    這篇文章主要介紹了JS highcharts動態(tài)柱狀圖原理及實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10
  • js關(guān)于精確計算和數(shù)值格式化以及直接引js文件

    js關(guān)于精確計算和數(shù)值格式化以及直接引js文件

    本文為大家介紹下關(guān)于精確計算和數(shù)值格式化以及直接引js文件,大家可以學(xué)習(xí)下
    2014-01-01
  • 小程序雙頭slider選擇器的實現(xiàn)示例

    小程序雙頭slider選擇器的實現(xiàn)示例

    這篇文章主要介紹了小程序雙頭slider選擇器的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • javascript iFrame研究

    javascript iFrame研究

    iFrame小應(yīng)用
    2008-12-12
  • JS排序之快速排序詳解

    JS排序之快速排序詳解

    這篇文章主要為大家詳細(xì)介紹了JS快速排序的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • javascript 鍵盤事件總結(jié) 推薦

    javascript 鍵盤事件總結(jié) 推薦

    在進入正題前,我們看一下瀏覽器對于鍵盤的一些默認(rèn)事件,這有助于我們用javascript截獲鍵盤事件。
    2009-12-12
  • 最新評論