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

資訊專欄INFORMATION COLUMN

JavaScript事件循環(huán)

Corwien / 2274人閱讀

摘要:事件循環(huán)當(dāng)主線程中的任務(wù)執(zhí)行完畢后,會從任務(wù)隊列中獲取任務(wù)一個個的放在棧中執(zhí)行去執(zhí)行,這個過程是循環(huán)不斷的,所以整個的這種運(yùn)行機(jī)制又稱為事件循環(huán)。

寫在前面

說起javascript(以下簡稱js)這門語言,相信大家已經(jīng)非常熟悉了,不管是前端開發(fā)還是后端開發(fā)幾乎無時無刻都要跟它打交道。雖說開發(fā)者每天幾乎都要操作js,但是你真的確定你掌握了js的運(yùn)行機(jī)制嗎!下面我們就來聊聊這話題。

JavaScript運(yùn)行機(jī)制圖解

上圖我們可以分為兩部分:瀏覽器中的JS引擎運(yùn)行環(huán)境Runtime,那它們的區(qū)別是什么?

JS引擎:編譯并執(zhí)行代碼的地方。

如上圖中可以看出JS引擎分為兩大核心部分:棧和堆

棧(Stack):js代碼的執(zhí)行都要壓到此棧中執(zhí)行。

堆:存放對象、數(shù)組的地方,js垃圾回收就是檢查這里。

Runtime:瀏覽器的運(yùn)行環(huán)境,它提供了一些對外接口供JS調(diào)用,如網(wǎng)絡(luò)請求接口。

JavaScript引擎是單線程的

JS引擎是單線程的,也就是說在一個時間段內(nèi),事情只能一件一件的按先后順序去做,第一件事沒做完就不能第二件事。那么在js引擎中負(fù)責(zé)解釋和執(zhí)行js代碼的線程只有一個,我們可以稱之為主線程

當(dāng)然瀏覽器的運(yùn)行環(huán)境Runtime還提供一些其他的線程,如定時器線程、ajax線程、事件線程、網(wǎng)絡(luò)請求和UI渲染的線程,為了和js主線程分開,我們這里都統(tǒng)稱它們?yōu)?b>工作線程。

由于瀏覽器是多線程的,所以工作線程和js主線程都可以執(zhí)行任務(wù),線程間互不干擾。

JavaScript同步(異步)任務(wù)

在JavaScript任務(wù)可以分為兩種:

同步任務(wù):在主線程上排隊執(zhí)行的任務(wù),只有前一個任務(wù)執(zhí)行完畢,才能執(zhí)行后一個任務(wù),若前一個任務(wù)耗費(fèi)很長時間,則后面的任務(wù)會一直處于等待狀態(tài),即阻塞狀態(tài)。

異步任務(wù):在棧執(zhí)行代碼的過程中,如遇到異步函數(shù),如setTimeout、異步Ajax、事件處理程序,會將這些異步代碼交給瀏覽器的工作線程來處理,我們把這些任務(wù)稱之為異步任務(wù)。異步任務(wù)是不進(jìn)入主線程,而是進(jìn)入任務(wù)隊列(queue task)。

什么異步函數(shù)?

異步函數(shù)通常是由發(fā)起函數(shù)回調(diào)函數(shù)構(gòu)成的。如:

A(callback)

函數(shù)A就是發(fā)起函數(shù)

callback就是回調(diào)函數(shù)

?

它們都是在主線程調(diào)用的,其中發(fā)起函數(shù)用來發(fā)起異步過程,回調(diào)函數(shù)用來處理結(jié)果。

如:`setTimeout(callback,1000)`

setTimeout就是發(fā)起函數(shù)、callback就是回調(diào)函數(shù)。

如:異步的Ajax
    var xhr = new new XMLHttpRequest();
    xhr.onreadystatechange = callback; //callback為回調(diào)函數(shù)
    xhr.open("get",url,true);
    xhr.send(null); // send為發(fā)起函數(shù)

可以看出發(fā)起函數(shù)和回調(diào)函數(shù)也可以是分離的。

?

既然同步任務(wù)是在主線程中執(zhí)行的,那么異步任務(wù)何時執(zhí)行?

答:是這樣的,一旦棧中同步任務(wù)執(zhí)行完畢后,系統(tǒng)就會通過事件循環(huán)機(jī)制讀取任務(wù)隊列中的任務(wù)一個個移到棧中去執(zhí)行。

?

事件循環(huán)

當(dāng)主線程中的任務(wù)執(zhí)行完畢后,會從任務(wù)隊列中獲取任務(wù)一個個的放在棧中執(zhí)行去執(zhí)行,這個過程是循環(huán)不斷的,所以整個的這種運(yùn)行機(jī)制又稱為事件循環(huán)。

在js中,代碼最終都是在棧中執(zhí)行的,棧結(jié)構(gòu)的特點(diǎn)是:先進(jìn)后出,后進(jìn)先出

我們來看下面代碼的運(yùn)行結(jié)果:

function bar(){
    console.log(1);
    foo();
}

function foo(){
    par();
    console.log(3);
}

function par(){
    setTimeout(function(){
        console.log(2);
    },0);
}

bar();

運(yùn)行的最終結(jié)果是:132。 為什么結(jié)果不是123呢?

下我們來分析下代碼運(yùn)行時入棧和出棧的過程。

首先當(dāng)調(diào)用函數(shù)bar()時,此函數(shù)就會先入棧,其內(nèi)部的console.log(1)也會隨之入棧執(zhí)行。

執(zhí)行完console.log(1)后,就要出棧,于是控制臺先打印出結(jié)果1,只剩下bar()在棧中。接著再執(zhí)行函數(shù)bar內(nèi)部的函數(shù)foo,于是函數(shù)foo也開心的入棧了。

執(zhí)行函數(shù)foo的內(nèi)部代碼,調(diào)用函數(shù)par(),于是函數(shù)par()也要跟著入棧。

由于函數(shù)par()內(nèi)部執(zhí)行遇到了異步函數(shù)setTimeout,異步函數(shù)則會由瀏覽器的Runtime運(yùn)行環(huán)境的工作線程來處理,等定時器設(shè)置的時間到達(dá)就會被放到任務(wù)隊列中,此時棧的同步任務(wù)繼續(xù)執(zhí)行。

接著在執(zhí)行par函數(shù)中的console.log(3),控制臺打印結(jié)果為3 ,此時棧的代碼執(zhí)行完畢后,會按照棧的特點(diǎn)進(jìn)行

先進(jìn)后出,后進(jìn)先出順序進(jìn)行出棧。出棧順序:先函數(shù)par()-->后函數(shù)foo()-->最后函數(shù)bar

最后只剩下異步任務(wù),由主線程去獲取任務(wù)隊列中的任務(wù)放在棧中去執(zhí)行。也可以認(rèn)為棧中的同步代碼執(zhí)行總是在讀取異步任務(wù)之前執(zhí)行。

最后執(zhí)行setTimeout中的回調(diào)函數(shù):結(jié)果控制臺輸出為2。

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

所以代碼的最終運(yùn)行結(jié)果為132。

小結(jié)

js引擎是單線程執(zhí)行js代碼,同步任務(wù)在棧中按順序執(zhí)行,如果某一個同步任務(wù)沒有執(zhí)行完畢,則后面的代碼將會處于阻塞等待狀態(tài)

棧中若執(zhí)行遇到了異步任務(wù)(如定時器、異步Ajax、事件),會將此異步任務(wù)通過瀏覽器對應(yīng)的工作線程來處理。

工作線程中的所有異步任務(wù)均會按照設(shè)定的時間進(jìn)行等待,時間一到會被加入任務(wù)隊列。如果是異步ajax,則等待其返回結(jié)果后在加入到任務(wù)隊列

當(dāng)棧中為空時,會通過事件循環(huán)來一個個獲取任務(wù)隊列中的任務(wù)放到棧中進(jìn)行逐個運(yùn)行。即棧中的同步任務(wù)總是在讀取異步任務(wù)之前執(zhí)行

定時器設(shè)置的時間不一定按照設(shè)定的時間進(jìn)行執(zhí)行,這得取決于棧中同步任務(wù)耗費(fèi)的時間。因?yàn)闂V袌?zhí)行的同步任務(wù)如果耗費(fèi)很長時間,則會影響到異步任務(wù)回調(diào)函數(shù)的執(zhí)行。

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

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

相關(guān)文章

  • 什么是JavaScript 事件循環(huán) ?

    摘要:此事件隊列的美妙之處在于它只是函數(shù)等待被調(diào)用和移動到調(diào)用棧的一個臨時存放區(qū)域。在事件循環(huán)不斷監(jiān)視調(diào)用棧是否為空現(xiàn)在確實(shí)是空的時候調(diào)用創(chuàng)建一個新的調(diào)用棧來執(zhí)行代碼。在執(zhí)行完之后進(jìn)入了一個新的狀態(tài)這個狀態(tài)調(diào)用棧為空事件記錄表為空事件隊列也為空。 這篇文章是對個人認(rèn)為講解 JavaScript 事件循環(huán)比較清楚的一篇英文文章的簡單翻譯,原文地址是http://altitudelabs.com...

    tracymac7 評論0 收藏0
  • JavaScript運(yùn)行機(jī)制和事件循環(huán)

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

    Ververica 評論0 收藏0
  • 總結(jié)javascript基礎(chǔ)概念(二):事件隊列循環(huán)

    摘要:而事件循環(huán)是主線程中執(zhí)行棧里的代碼執(zhí)行完畢之后,才開始執(zhí)行的。由此產(chǎn)生的異步事件執(zhí)行會作為任務(wù)隊列掛在當(dāng)前循環(huán)的末尾執(zhí)行。在下,觀察者基于監(jiān)聽事件的完成情況在下基于多線程創(chuàng)建。 主要問題: 1、JS引擎是單線程,如何完成事件循環(huán)的? 2、定時器函數(shù)為什么計時不準(zhǔn)確? 3、回調(diào)與異步,有什么聯(lián)系和不同? 4、ES6的事件循環(huán)有什么變化?Node中呢? 5、異步控制有什么難點(diǎn)?有什么解決方...

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

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

    Shisui 評論0 收藏0
  • 事件循環(huán)與任務(wù)隊列

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

    SQC 評論0 收藏0
  • JavaScript事件循環(huán)(Event Loop)

    摘要:事件循環(huán)的順序,決定代碼執(zhí)行的順序。輸出第二輪事件循環(huán)正式結(jié)束三第三輪事件循環(huán)第三輪事件循環(huán)從宏任務(wù)開始。記為遇到,立即執(zhí)行回調(diào)函數(shù)放入中注冊,然后被分發(fā)到微任務(wù)事件隊列中。 1、為什么要有事件循環(huán)? 因?yàn)閖s是單線程的,事件循環(huán)是js的執(zhí)行機(jī)制,也是js實(shí)現(xiàn)異步的一種方法。 既然js是單線程,那就像只有一個窗口的銀行,客戶需要排隊一個一個辦理業(yè)務(wù),同理js任務(wù)也要一個一個順序執(zhí)行。如...

    dmlllll 評論0 收藏0

發(fā)表評論

0條評論

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