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

資訊專欄INFORMATION COLUMN

事件循環(huán)與任務隊列

SQC / 2240人閱讀

摘要:需要注意的是,定時器比較特殊,并沒有把回調(diào)函數(shù)掛在事件循環(huán)隊列中,它所做的就是設置一個定時器,當定時器到時后,環(huán)境會把你的回調(diào)函數(shù)放在事件循環(huán)中,這樣,在未來某個時刻的會被取出執(zhí)行。

Author: bugall
Wechat: bugallF
Email: [email protected]
Github: https://github.com/bugall

一: 事件循環(huán)

雖然我們用Javascript總是可以實現(xiàn)一些異步代碼, 但是Javascript中真正的異步概念,但是直到ES6,Javascript才內(nèi)建了直接的異步概念。

對于原有Javascript引擎來說, 它只關(guān)心如何去執(zhí)行給定的代碼塊, 對于什么時候該執(zhí)行哪些代碼塊這個是引擎不關(guān)心的。引擎是依賴于宿主環(huán)境的,這里的宿主環(huán)境并不是指操作系統(tǒng)環(huán)境,因為不同的平臺提供的“可執(zhí)行環(huán)境”不同。而宿主環(huán)境就是為了隔離代碼、語言與具體的平臺而提出的一個設計。比如web瀏覽器環(huán)境,Node.js這樣的工具等,所有的這些環(huán)境都有一個共同點,它們都提供了一種機制來處理程序中多個代碼塊的執(zhí)行,且執(zhí)行每塊時調(diào)用Javascript引擎,這種機制被成為事件循環(huán)。

換句話說,Javascript引擎本身并沒有時間的概念,只是一個按需執(zhí)行Javascript任意代碼片段的環(huán)境。“事件”的調(diào)度總是由包含它的環(huán)境進行。

注意?。?!,ES6后事件的管理方式有所改變。ES6本身解決的事件在哪里管理的問題,現(xiàn)在ES6精確指定了事件循環(huán)的工作細節(jié),這就 意味著技術(shù)上將其納如了Javascript引擎的勢力范圍,而不再由宿主環(huán)境管理,這個改變的一個主要原因是ES6中Promise的引入,這個技術(shù)要求事件循環(huán)隊列的調(diào)度運行能夠直接進行精細的控制

我們看下面的這段代碼:

function task() {
    console.log("Hello Word");
}
setTimeout(task, 1000);

如果你在代碼中設置一個計時器, 當計時器到達指定的時間后執(zhí)行函數(shù)task, 當Javascript引擎執(zhí)行到定時器的時候會通知宿主環(huán)境:“我要去做別的事情, 等1秒后就調(diào)用task函數(shù),注意:是調(diào)用而不是執(zhí)行)

我們用一段偽代碼實現(xiàn)一個簡單的事件循環(huán)

var eventList = [event1, event2, event3];
var event;
while(true) {
    if (eventList.length > 0 ) {
        event = eventList.pop();
    }
    run(event);
}

可以看到有一個用while循環(huán)實現(xiàn)的持續(xù)運行的循環(huán),當event1, event2, event3都取出被執(zhí)行一次后稱為一輪,循環(huán)的每一輪稱為一個tick,對于每一個tick而言,如果在隊列中有等待的事件,那么就會從隊列中取出下一個事件并執(zhí)行,這些事件就是我們代碼中寫的回調(diào)函數(shù)。

需要注意的是,定時器比較特殊,setTimeout(task, 1000)并沒有把回調(diào)函數(shù)掛在事件循環(huán)隊列中,它所做的就是設置一個定時器,當定時器到時后,環(huán)境會把你的回調(diào)函數(shù)放在事件循環(huán)中,這樣,在未來某個時刻的tick會被取出執(zhí)行。

如果你的事件循環(huán)中已經(jīng)有很多項目后,定時器的回調(diào)就要被放到隊尾( 不支持搶占式 )等待被執(zhí)行,這也就是定時器不準的原因。定時器的回調(diào)函數(shù)的執(zhí)行要根據(jù)時間隊列的狀態(tài)而定。
那么該如何去降低定時器誤差呢?

二:任務隊列

嚴格來說,定時器并不直接把回調(diào)函數(shù)直接插到事件循環(huán)隊列,定時器會在有機會的時候插入事件,對于連續(xù)的兩個setTimeout(..., 0)調(diào)用不能保證會嚴格按照調(diào)用順序處理,所以各種情況都會發(fā)生,比如定時器漂移,這類結(jié)果是不可預測的,在Node.js中可以用process.nextTick(...)。但是不能保證所有環(huán)境都能控制異步的順序。

在ES6中,在事件循環(huán)隊列上有個一個新的概念,那就是任務隊列,這個概念給大家?guī)淼淖畲笥绊懣赡芫褪?b>Promise的異步特性

任務隊列就是掛在時間循環(huán)隊列的每個tick之后的一個隊列,在事件循環(huán)的每個tick中,可能出現(xiàn)的異步動作不會導致一個完整的新事件添加到事件循環(huán)隊列中,而會在當前tick的任務隊列末尾添加一個任務。
一個任務可能引起更多任務被添加到同一個隊列末尾,所以理論上說,任務循環(huán)可能無限循環(huán),無法轉(zhuǎn)移到下一個事件循環(huán)tick.

任務隊列的概念,那么怎么減少定時器的誤差?看代碼:

function task() {
    console.log("Hello Word");
}
setTimeout(task, 1000);

如果現(xiàn)在時間隊列中有100個等待被執(zhí)行的任務,這時候task任務準備插入到事件隊列。

沒有引入任務隊列前:
task會被插入到當前事件循環(huán)隊列的末端,等待下次的tick被執(zhí)行,那么這就需要等到當前的tick被執(zhí)行完,那么這時候的timer延時就決定于100個等待執(zhí)行的任務耗時。

引入任務隊列之后:
直接插入到當前tick的任務隊列被執(zhí)行

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

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

相關(guān)文章

  • JavaScript運行機制和事件循環(huán)

    摘要:主線程不斷重復上面的三步,此過程也就是常說的事件循環(huán)。所以主線程代碼執(zhí)行時間過長,會阻塞事件循環(huán)的執(zhí)行。參考資料這一次,徹底弄懂執(zhí)行機制任務隊列的順序機制事件循環(huán)搞懂異步事件輪詢與中的事件循環(huán) 1. 說明 讀過本文章后,您能知道: JavaScript代碼在瀏覽器中的執(zhí)行機制和事件循環(huán) 面試中經(jīng)常遇到的代碼輸出順序問題 首先通過一段代碼來驗證你是否了解代碼輸出順序,如果你不知道輸出...

    Ververica 評論0 收藏0
  • 今天,我明白了JS事件循環(huán)機制

    摘要:而這些隊列由的事件循環(huán)來搞定宏任務與微任務,在最新標準中,它們被分別稱為與。我們梳理一下事件循環(huán)的執(zhí)行機制循環(huán)首先從宏任務開始,遇到,生成執(zhí)行上下文,開始進入執(zhí)行棧,可執(zhí)行代碼入棧,依次執(zhí)行代碼,調(diào)用完成出棧。 寫在前面 js是一門單線程的編程語言,也就是說js在處理任務的時候,所有任務只能在一個線程上排隊被執(zhí)行,那如果某一個任務耗時比較長呢?總不能等到它執(zhí)行結(jié)束再去執(zhí)行下一個。所以在...

    maochunguang 評論0 收藏0
  • 總結(jié):JavaScript異步、事件循環(huán)消息隊列、微任務任務

    摘要:單線程異步非阻塞然后,這又牽扯到了事件循環(huán)消息隊列,還有微任務宏任務這些。此步的位置不確定某個時刻后,定時器觸發(fā)線程通知事件觸發(fā)線程,事件觸發(fā)線程將回調(diào)函數(shù)加入消息隊列隊尾,等待引擎線程執(zhí)行。 前言 Philip Roberts 在演講 great talk at JSConf on the event loop 中說:要是用一句話來形容 JavaScript,我可能會這樣: Java...

    qianfeng 評論0 收藏0
  • JavaScript單線程事件循環(huán)(Event Loop)那些事

    摘要:概述本篇主要介紹的運行機制單線程事件循環(huán)結(jié)論先在中利用運行至完成和非阻塞完成單線程下異步任務的處理就是先處理主模塊主線程上的同步任務再處理異步任務異步任務使用事件循環(huán)機制完成調(diào)度涉及的內(nèi)容有單線程事件循環(huán)同步執(zhí)行異步執(zhí)行定時器的事件循環(huán)開始 1.概述 本篇主要介紹JavaScript的運行機制:單線程事件循環(huán)(Event Loop). 結(jié)論先: 在JavaScript中, 利用運行至...

    Shisui 評論0 收藏0
  • 淺談不同環(huán)境下的JavaScript執(zhí)行機制 + 示例詳解

    摘要:如果沒有其他異步任務要處理比如到期的定時器,會一直停留在這個階段,等待請求返回結(jié)果。執(zhí)行的執(zhí)行事件關(guān)閉請求的,例如事件循環(huán)的每一次循環(huán)都需要依次經(jīng)過上述的階段。因此,才會早于執(zhí)行。 showImg(https://segmentfault.com/img/bVbnY76); 概念 同步任務(Synchronous) 在主線程上排隊執(zhí)行的任務,只有前一個任務執(zhí)行完畢,才能執(zhí)行后一個任務 ...

    wanghui 評論0 收藏0

發(fā)表評論

0條評論

SQC

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<