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

資訊專(zhuān)欄INFORMATION COLUMN

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

mykurisu / 2116人閱讀

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

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

console.log(222);

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

JS的特點(diǎn)

在聊Event Loop之前,有必要先講講JS的一些重要特點(diǎn)

JS的單線程

JS的一大特點(diǎn)就是單線程,也就是說(shuō),同一個(gè)時(shí)間只能做一件事。那么,為什么JS不能有多個(gè)線程呢?

第一,為了提高效率,減少CPU的開(kāi)銷(xiāo)。在多線程中,CPU需要來(lái)回切換線程,就會(huì)存在線程切換上的開(kāi)銷(xiāo)。

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

JS的異步

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

任務(wù)隊(duì)列

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

這個(gè)時(shí)候,任務(wù)隊(duì)列就派上用場(chǎng)了。

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

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

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

值得一提的是,任務(wù)隊(duì)列不止一條。由于異步任務(wù)有很多種,比如事件監(jiān)聽(tīng)類(lèi),定時(shí)器類(lèi),Ajax請(qǐng)求類(lèi)...所以可以有很多條任務(wù)隊(duì)列

這樣說(shuō)大家可能還不太明白,我畫(huà)個(gè)圖解釋下

Event Loop

主線程從"任務(wù)隊(duì)列"中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱(chēng)為Event Loop(事件輪詢(xún))。
執(zhí)行流程

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

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

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

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

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

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引擎中其實(shí)是這樣執(zhí)行的

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

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

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

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

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

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

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

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

知道這個(gè)機(jī)制后,我們?cè)倩仡^看看那個(gè)面試題

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

console.log(222);

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

總結(jié)

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

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

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

相關(guān)文章

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

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

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

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

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

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

    levius 評(píng)論0 收藏0
  • 前端資源收集整理

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

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

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

0條評(píng)論

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