国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

前端碎碎念 之 nextTick, setTimeout 以及 setImmediate 三者的執(zhí)行

Cciradih / 3236人閱讀

摘要:更多文章請前往我的個人博客這個問題是有關(guān)執(zhí)行順序和的。其中,整體代碼,可以理解為待執(zhí)行的所有代碼。當(dāng)隊列執(zhí)行完后再執(zhí)行一個任務(wù)。然后再次回到新的事件循環(huán)。所以兩個執(zhí)行完后隊列里只剩下第一個里的。

『前端碎碎念』系列會記錄我平時看書或者看文章遇到的問題,一般都是比較基礎(chǔ)但是容易遺忘的知識點(diǎn),你也可能會在面試中碰到。 我會查閱一些資料并可能加上自己的理解,來記錄這些問題。更多文章請前往我的個人博客

這個問題是有關(guān)執(zhí)行順序和Event Loop的。關(guān)于Event Loop和任務(wù)隊列等概念,可以先閱讀我引用中的文章,本文主要分析一些存在的疑惑點(diǎn)。

下面這個例子比較典型:

setImmediate(function(){
    console.log(1);
},0);
setTimeout(function(){
    console.log(2);
},0);
new Promise(function(resolve){
    console.log(3);
    resolve();
    console.log(4);
}).then(function(){
    console.log(5);
});
console.log(6);
process.nextTick(function(){
    console.log(7);
});
console.log(8);

//輸出結(jié)果是3 4 6 8 7 5 2 1

在解釋輸出結(jié)果之前,我們來看幾個概念:

macro-task: script (整體代碼),setTimeout, setInterval, setImmediate, I/O, UI rendering.
micro-task: process.nextTick, Promise(原生),Object.observe,MutationObserver

除了script整體代碼,micro-task的任務(wù)優(yōu)先級高于macro-task的任務(wù)優(yōu)先級。
其中,script(整體代碼) ,可以理解為待執(zhí)行的所有代碼。

所以執(zhí)行順序如下:

第一步. script整體代碼被執(zhí)行,執(zhí)行過程為

創(chuàng)建setImmediate macro-task

創(chuàng)建setTimeout macro-task

創(chuàng)建micro-task Promise.then 的回調(diào),并執(zhí)行script console.log(3); resolve(); console.log(4); 此時輸出3和4,雖然resolve調(diào)用了,執(zhí)行了但是整體代碼還沒執(zhí)行完,無法進(jìn)入Promise.then 流程。

console.log(6)輸出6

process.nextTick 創(chuàng)建micro-task

console.log(8) 輸出8

第一個過程過后,已經(jīng)輸出了3 4 6 8

第二步. 由于其他micro-task 的 優(yōu)先級高于macro-task。
此時micro-task 中有兩個任務(wù)按照優(yōu)先級process.nextTick 高于 Promise。
所以先輸出7,再輸出5

第三步,micro-task 任務(wù)列表已經(jīng)執(zhí)行完畢,家下來執(zhí)行macro-task. 由于setTimeout的優(yōu)先級高于setIImmediate,所以先輸出2,再輸出1。

整個過程描述起來像是同步操作,實(shí)際上是基于Event Loop的事件循環(huán)。

關(guān)于micro-task和macro-task的執(zhí)行順序,可看下面這個例子(來自《深入淺出Node.js》):

//加入兩個nextTick的回調(diào)函數(shù)
process.nextTick(function () {
    console.log("nextTick延遲執(zhí)行1");
});
process.nextTick(function () { 
    console.log("nextTick延遲執(zhí)行2");
});
// 加入兩個setImmediate()的回調(diào)函數(shù)
setImmediate(function () {
    console.log("setImmediate延遲執(zhí)行1"); 
    // 進(jìn)入下次循環(huán) 
    process.nextTick(function () {
        console.log("強(qiáng)勢插入");
    });
});
setImmediate(function () {
    console.log("setImmediate延遲執(zhí)行2"); 
});

console.log("正常執(zhí)行");

書中給出的執(zhí)行結(jié)果是:

正常執(zhí)行
nextTick延遲執(zhí)行1
nextTick延遲執(zhí)行2
setImmediate延遲執(zhí)行1
強(qiáng)勢插入
setImmediate延遲執(zhí)行2

process.nextTick在兩個setImmediate之間強(qiáng)行插入了。
但運(yùn)行這段代碼發(fā)現(xiàn)結(jié)果卻是這樣:

正常執(zhí)行
nextTick延遲執(zhí)行1
nextTick延遲執(zhí)行2
setImmediate延遲執(zhí)行1
setImmediate延遲執(zhí)行2
強(qiáng)勢插入

樸老師寫那本書的時候,node最新版本為0.10.13,而我的版本是6.x

老版本的Node會優(yōu)先執(zhí)行process.nextTick。
當(dāng)process.nextTick隊列執(zhí)行完后再執(zhí)行一個setImmediate任務(wù)。然后再次回到新的事件循環(huán)。所以執(zhí)行完第一個setImmediate后,隊列里只剩下第一個setImmediate里的process.nextTick和第二個setImmediate。所以process.nextTick會先執(zhí)行。

而在新版的Node中,process.nextTick執(zhí)行完后,會循環(huán)遍歷setImmediate,將setImmediate都執(zhí)行完畢后再跳出循環(huán)。所以兩個setImmediate執(zhí)行完后隊列里只剩下第一個setImmediate里的process.nextTick。最后輸出"強(qiáng)勢插入"。

具體實(shí)現(xiàn)可參考Node.js源碼。

關(guān)于優(yōu)先級的另一個比較清晰的版本:

觀察者優(yōu)先級

在每次輪訓(xùn)檢查中,各觀察者的優(yōu)先級分別是:

idle觀察者 > I/O觀察者 > check觀察者。

idle觀察者:process.nextTick

I/O觀察者:一般性的I/O回調(diào),如網(wǎng)絡(luò),文件,數(shù)據(jù)庫I/O等

check觀察者:setImmediate,setTimeout

setImmediate 和 setTimeout 的優(yōu)先級

看下面這個例子:

setImmediate(function () {
    console.log("1"); 
});
setTimeout(function () {
    console.log("2"); 
}, 0);

console.log("3");

//輸出結(jié)果是3 2 1

我們知道現(xiàn)在HTML5規(guī)定setTimeout的最小間隔時間是4ms,也就是說0實(shí)際上也會別默認(rèn)設(shè)置為最小值4ms。我們把這個延遲加大

上面說到setTimeout 的優(yōu)先級比 setImmediate的高,其實(shí)這種說法是有條件的。

再看下面這個例子,為setTimeout增加了一個延遲20ms的時間:

setImmediate(function () {
    console.log("1"); 
});
setTimeout(function () {
    console.log("2"); 
}, 20);

console.log("3");

//輸出結(jié)果是3 2 1

setTimeout延遲20ms再執(zhí)行,而setImmediate是立即執(zhí)行,竟然2比1還先輸出??

試試打印出這個程序的執(zhí)行時間:

var t1 = +new Date();
setImmediate(function () {
    console.log("1"); 
});
setTimeout(function () {
    console.log("2"); 
},20);

console.log("3");
var t2 = +new Date();
console.log("time: " + (t2 - t1));
//輸出
3 
time: 23 
2 
1

程序執(zhí)行用了23ms, 也就是說,在script(整體代碼)執(zhí)行完之前,setTimeout已經(jīng)過時了,所以當(dāng)進(jìn)入macro-task的時候setTimeout依然優(yōu)先于setImmediate執(zhí)行。如果我們把這個值調(diào)大一點(diǎn)呢?

var t1 = +new Date();
setImmediate(function () {
    console.log("1"); 
});
setTimeout(function () {
    console.log("2"); 
},30);

console.log("3");
var t2 = +new Date();
console.log("time: " + (t2 - t1));
//輸出
3 
time: 23 
1 
2

setImmediate早于setTimeout執(zhí)行了,因為進(jìn)入macro-task 循環(huán)的時候,setTimeout的定時器還沒到。

以上實(shí)驗是基于6.6.0版本Node.js測試,實(shí)際上在碰到類似這種問題的時候,最好的辦法是參考標(biāo)準(zhǔn),并查閱源碼,不能死記概念和順序,因為標(biāo)準(zhǔn)也是會變的。包括此文也是自學(xué)總結(jié),經(jīng)供參考。

參考:
https://www.zhihu.com/questio...
https://segmentfault.com/a/11...
http://www.jianshu.com/p/837b...

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

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/86791.html

相關(guān)文章

  • Node中事件循環(huán)和異步API

    摘要:異步在中,是在單線程中執(zhí)行的沒錯,但是內(nèi)部完成工作的另有線程池,使用一個主進(jìn)程和多個線程來模擬異步。在事件循環(huán)中,觀察者會不斷的找到線程池中已經(jīng)完成的請求對象,從中取出回調(diào)函數(shù)和數(shù)據(jù)并執(zhí)行。 1. 介紹 單線程編程會因阻塞I/O導(dǎo)致硬件資源得不到更優(yōu)的使用。多線程編程也因為編程中的死鎖、狀態(tài)同步等問題讓開發(fā)人員頭痛。Node在兩者之間給出了它的解決方案:利用單線程,遠(yuǎn)離多線程死鎖、狀態(tài)...

    atinosun 評論0 收藏0
  • 瀏覽器和Node中事件循環(huán)機(jī)制

    摘要:二瀏覽器端在講解事件循環(huán)之前先談?wù)勚型酱a異步代碼的執(zhí)行流程。三端我自己認(rèn)為的事件循環(huán)和瀏覽器端還是有點(diǎn)區(qū)別的,它的事件循環(huán)依靠引擎。四總結(jié)本篇主要介紹了瀏覽器和對于事件循環(huán)機(jī)制實(shí)現(xiàn),由于能力水平有限,其中可能有誤之處歡迎指出。 一、前言 前幾天聽公司一個公司三年的前端說今天又學(xué)到了一個知識點(diǎn)-微任務(wù)、宏任務(wù),我問他這是什么東西,由于在吃飯他淺淺的說了下,當(dāng)時沒太理解就私下學(xué)習(xí)整理一...

    KevinYan 評論0 收藏0
  • Node.js Event LoopTimers, process.nextTick()

    摘要:前言以異步和事件驅(qū)動的特性著稱但異步是怎么實(shí)現(xiàn)的呢其中核心的一部分就是下文中內(nèi)容基本來自于文檔有不準(zhǔn)確地方請指出什么是能讓的操作表現(xiàn)得無阻塞盡管是單線程的但通過盡可能的將操作放到操作系統(tǒng)內(nèi)核由于現(xiàn)在大多數(shù)內(nèi)核都是多線程的它們可以在后臺執(zhí)行多 前言 Node.js以異步I/O和事件驅(qū)動的特性著稱,但異步I/O是怎么實(shí)現(xiàn)的呢?其中核心的一部分就是event loop,下文中內(nèi)容基本來自于N...

    sarva 評論0 收藏0
  • 瀏覽器與NodeJSEventLoop異同,以及部分機(jī)制。

    摘要:瀏覽器與的異同,以及部分機(jī)制有人對部分迷惑,本身構(gòu)造函數(shù)是同步的,是異步。瀏覽器的的已全部分析完成,過程中引用阮一峰博客,知乎,部分文章內(nèi)容,侵刪。 瀏覽器與NodeJS的EventLoop異同,以及部分機(jī)制 PS:有人對promise部分迷惑,Promise本身構(gòu)造函數(shù)是同步的,.then是異步。---- 2018/7/6 22:35修改 javascript 是一門單線程的腳本...

    jubincn 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<