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

資訊專欄INFORMATION COLUMN

『前端干貨篇』: 你不知道的Event Loop

mykurisu / 2114人閱讀

摘要:任務(wù)隊列中的任務(wù)事件,一般有個共性就是存在回調(diào)函數(shù)。存放異步執(zhí)行的代碼,如定時器事件監(jiān)聽回調(diào)函數(shù)等,進(jìn)入等待狀態(tài)。總結(jié)的事件輪詢的機制,使任務(wù)隊列主線程異步操作之間可以相互協(xié)作。

從一道面試題說起
setTimeout(function() {
  console.log(111);
}, 0);   // 這里定時器時間設(shè)置為0ms后執(zhí)行

console.log(222);

相信這道題很多人都看過,結(jié)果是先輸出222,再輸出111
可能新手會犯錯,認(rèn)為定時器設(shè)置0毫秒就等于立即就執(zhí)行,所以先輸出111。但其實內(nèi)部涉及一個很重要的JS運行機制,也就是我們今天的主角——事件輪詢(Event Loop)

JS的特點

在聊Event Loop之前,有必要先講講JS的一些重要特點

JS的單線程

JS的一大特點就是單線程,也就是說,同一個時間只能做一件事。那么,為什么JS不能有多個線程呢?

第一,為了提高效率,減少CPU的開銷。在多線程中,CPU需要來回切換線程,就會存在線程切換上的開銷。

第二,JS最初設(shè)計時,是作為瀏覽器的腳本語言,主要用途是與用戶互動,以及操作DOM。這就決定了它只能是單線程,否則會帶來很復(fù)雜的同步問題。比如,假定JS同時有兩個線程,一個線程在某個DOM節(jié)點上添加內(nèi)容,另一個線程刪除了這個節(jié)點,這時瀏覽器應(yīng)該以哪個線程為準(zhǔn)?

JS的異步

說到JS的異步,可能有同學(xué)會問啦,JS是單線程的怎么還能異步執(zhí)行,這不是自相矛盾嗎?的確,單線程和異步確實不能同時成為一個語言的特性,所以它本身不可能是異步的。一定是存在一種機制讓它能夠異步執(zhí)行,往下看!

任務(wù)隊列

JS是單線程就意味著,所有任務(wù)需要排隊,等前一個任務(wù)結(jié)束,才能執(zhí)行后一個任務(wù)。但前端的某些任務(wù)是非常耗時的,例如IO設(shè)備(輸入輸出設(shè)備)、Ajax操作(從網(wǎng)絡(luò)讀取數(shù)據(jù))、定時器...不得不等著結(jié)果出來,再往下執(zhí)行。如果讓他們和別的任務(wù)一樣,都老老實實的排隊等待執(zhí)行的話,執(zhí)行效率會非常的低,甚至導(dǎo)致頁面的假死,用戶體驗很差。

這個時候,任務(wù)隊列就派上用場了。

在JS中,所有任務(wù)可以分成兩種。一種是同步任務(wù),另一種是異步任務(wù)。

同步任務(wù)指的是,在主線程上排隊執(zhí)行的任務(wù),只有前一個任務(wù)執(zhí)行完畢,才能執(zhí)行后一個任務(wù);異步任務(wù)指的是,不進(jìn)入主線程,而進(jìn)入"任務(wù)隊列"的任務(wù),只有"任務(wù)隊列"通知主線程,某個異步任務(wù)可以執(zhí)行了,該任務(wù)才會進(jìn)入主線程執(zhí)行。

任務(wù)隊列中的任務(wù)事件,一般有個共性就是存在"回調(diào)函數(shù)"。所謂"回調(diào)函數(shù)",就是那些會被主線程掛起來的代碼。異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)主線程開始執(zhí)行異步任務(wù)時,執(zhí)行就是對應(yīng)的回調(diào)函數(shù)。

值得一提的是,任務(wù)隊列不止一條。由于異步任務(wù)有很多種,比如事件監(jiān)聽類,定時器類,Ajax請求類...所以可以有很多條任務(wù)隊列

這樣說大家可能還不太明白,我畫個圖解釋下

Event Loop

主線程從"任務(wù)隊列"中讀取事件,這個過程是循環(huán)不斷的,所以整個的這種運行機制又稱為Event Loop(事件輪詢)。
執(zhí)行流程

(1)所有同步任務(wù)都在主線程上執(zhí)行,形成一個執(zhí)行棧(每執(zhí)行一條代碼,向棧中壓入這條代碼)。

(2)主線程之外,還存在一個"任務(wù)隊列"。存放異步執(zhí)行的代碼,如定時器、事件監(jiān)聽回調(diào)函數(shù)等,進(jìn)入等待狀態(tài)。

(3)一旦主線程中的所有同步任務(wù)執(zhí)行完畢,就會讀取"任務(wù)隊列",看看里面有哪些任務(wù)。那些對應(yīng)的異步任務(wù),于是結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行。

(4)主線程不斷重復(fù)上面的第三步(輪詢)。

具體舉個例子吧
假如我們有一段代碼

var a = 11111
console.log(a)

var btn1 = document.getElementById("btn1")
btn1.onclick = function() {
    console.log(22222)
}

var btn2 = document.getElementById("btn2")
btn2.onclick = function() {
    console.log(33333)
}

setTimeout(function() {
  console.log(44444)
}, 1000)

console.log(55555)

以上代碼在JS引擎中其實是這樣執(zhí)行的

var a = 11111
console.log(a)
var btn1 = document.getElementById("btn1")
var btn2 = document.getElementById("btn2")
console.log(55555)

這五句代碼是同步代碼,會直接進(jìn)入主線程,依次執(zhí)行

btn.onclick = function() {
    console.log(22222)
}

btn2.onclick = function() {
    console.log(33333)
}

setTimeout(function() {
  console.log(44444)
}, 1000)

這三塊異步代碼不會直接進(jìn)入主線程,而是先在相應(yīng)的任務(wù)隊列中注冊

當(dāng)主線程執(zhí)行完所有同步代碼時,就開始不斷輪詢?nèi)蝿?wù)隊列是否有任務(wù)需要執(zhí)行,輪詢的過程很快。在輪詢過程中,要是用戶點擊了btn1按鈕,任務(wù)隊列會通知主線程,"說我這有異步代碼已就緒,需要你來執(zhí)行"。這時btn1.onclick就從任務(wù)隊列中彈出,到主線程中執(zhí)行

同樣的,當(dāng)過了1s時,任務(wù)隊列會通知定時器需要執(zhí)行,這時主線程輪詢時得到這條"通知",所以就執(zhí)行定時器中語句

知道這個機制后,我們再回頭看看那個面試題

setTimeout(function() {
  console.log(111);
}, 0);   // 這里定時器時間設(shè)置為0ms后執(zhí)行

console.log(222);

這里的console.log(222) 首先在主線程中執(zhí)行,而定時器則是先在任務(wù)隊列中注冊。當(dāng)主線程中代碼執(zhí)行完(也就是console.log("222")這條語句執(zhí)行完后),主線程開始輪詢?nèi)蝿?wù)隊列中的異步代碼,由于定時器設(shè)置的時間是0ms,所以任務(wù)隊列會立即通知主線程,可以執(zhí)行。最后定時器就會到主線程中開始執(zhí)行。這就是為什么打印的結(jié)果先是222,后111。

總結(jié)

JS的事件輪詢的機制,使任務(wù)隊列、JS主線程、異步操作之間可以相互協(xié)作。這正是JS語言與眾不同的運行方式,也因此使它具備了其他語言不具備的優(yōu)勢。
最后感謝大家百忙之中辛苦觀看,也希望這篇文章可以幫助屏幕前的你更好的理解JS的Event Loop機制!

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

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

相關(guān)文章

  • 優(yōu)秀文章收藏(慢慢消化)持續(xù)更新~

    摘要:整理收藏一些優(yōu)秀的文章及大佬博客留著慢慢學(xué)習(xí)原文協(xié)作規(guī)范中文技術(shù)文檔協(xié)作規(guī)范阮一峰編程風(fēng)格凹凸實驗室前端代碼規(guī)范風(fēng)格指南這一次,徹底弄懂執(zhí)行機制一次弄懂徹底解決此類面試問題瀏覽器與的事件循環(huán)有何區(qū)別筆試題事件循環(huán)機制異步編程理解的異步 better-learning 整理收藏一些優(yōu)秀的文章及大佬博客留著慢慢學(xué)習(xí) 原文:https://www.ahwgs.cn/youxiuwenzhan...

    JeOam 評論0 收藏0
  • 【回顧九月份第二周】 前端你該知道事兒

    摘要:順便一說,這首歌的原唱是秋田,中島當(dāng)年嗓子壞了,才有這歌。中文是直接翻譯來的,作曲是秋田。一部電影春夏秋冬又一春春夏秋冬又一春是由金基德執(zhí)導(dǎo),金英民吳英秀金基德主演的一部韓國電影。年月日于韓國上映。 原鏈接: http://bluezhan.me/weekly/#/9-2 1、web前端 Angular vs. React vs. Vue: A 2017 comparison 9 S...

    sixgo 評論0 收藏0
  • 【回顧九月份第二周】 前端你該知道事兒

    摘要:順便一說,這首歌的原唱是秋田,中島當(dāng)年嗓子壞了,才有這歌。中文是直接翻譯來的,作曲是秋田。一部電影春夏秋冬又一春春夏秋冬又一春是由金基德執(zhí)導(dǎo),金英民吳英秀金基德主演的一部韓國電影。年月日于韓國上映。 原鏈接: http://bluezhan.me/weekly/#/9-2 1、web前端 Angular vs. React vs. Vue: A 2017 comparison 9 S...

    levius 評論0 收藏0
  • 前端資源收集整理

    摘要:工作原因,最近一年斷斷續(xù)續(xù)寫了一點前端代碼,收集整理了一些資料,和大家共享。 工作原因,最近一年斷斷續(xù)續(xù)寫了一點前端代碼,收集整理了一些資料,和大家共享。 Github版本:Front-End Resource Collection 前端相關(guān)資源匯總 學(xué)習(xí)指導(dǎo) 精華文章 Web前端的路該怎么走?:文章超長,但是干貨超級多,值得反復(fù)精讀! 聽說2017你想寫前端?:適合于已經(jīng)度過了小白階...

    awesome23 評論0 收藏0

發(fā)表評論

0條評論

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