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

資訊專欄INFORMATION COLUMN

淺談JavaScript中的事件循環(huán)機(jī)制

Pluser / 3144人閱讀

摘要:事件循環(huán)背景是一門單線程非阻塞的腳本語言,單線程意味著,代碼在執(zhí)行的任何時(shí)候,都只有一個(gè)主線程來處理所有的任務(wù)。在意識(shí)到該問題之際,新特性中的可以讓成為一門多線程語言,但實(shí)際開發(fā)中使用存在著諸多限制。這個(gè)地方被稱為執(zhí)行棧。

事件循環(huán)(Event Loop) 背景

JavaScript是一門單線程非阻塞的腳本語言,單線程意味著,JavaScript代碼在執(zhí)行的任何時(shí)候,都只有一個(gè)主線程來處理所有的任務(wù)。而非阻塞則是當(dāng)代碼需要進(jìn)行一項(xiàng)異步任務(wù)(無法立刻返回結(jié)果,需要花一定時(shí)間才能返回的任務(wù),如I/O事件)的時(shí)候,主線程會(huì)掛起(pending)這個(gè)任務(wù),然后在異步任務(wù)返回結(jié)果的時(shí)候再根據(jù)一定規(guī)則去執(zhí)行相應(yīng)的回調(diào)。
在意識(shí)到該問題之際,html5新特性中的web worker可以讓JavaScript成為一門多線程語言,但實(shí)際開發(fā)中使用web worker存在著諸多限制。

瀏覽器的Event Loop js引擎的過程 同步編程案例

思考一下這段代碼的結(jié)果?

顯然,同步函數(shù)是由上至下的執(zhí)行順序

異步編程案例

因?yàn)閟etTimeout是異步函數(shù),js執(zhí)行機(jī)制是先將同步函數(shù)執(zhí)行完畢,再執(zhí)行異步函數(shù)

執(zhí)行棧與事件隊(duì)列

當(dāng)javascript代碼執(zhí)行的時(shí)候會(huì)將不同的變量存于內(nèi)存中的不同位置:堆(heap)和棧(stack)中來加以區(qū)分。其中,堆里存放著一些對(duì)象。而棧中則存放著一些基礎(chǔ)類型變量以及對(duì)象的指針。如下:

當(dāng)我們調(diào)用一個(gè)方法的時(shí)候,js會(huì)生成一個(gè)與這個(gè)方法對(duì)應(yīng)的執(zhí)行環(huán)境(context),又叫執(zhí)行上下文。這個(gè)執(zhí)行環(huán)境中存在著這個(gè)方法的私有作用域,上層作用域的指向,方法的參數(shù),這個(gè)作用域中定義的變量以及這個(gè)作用域的this對(duì)象。 而當(dāng)一系列方法被依次調(diào)用的時(shí)候,因?yàn)閖s是單線程的,同一時(shí)間只能執(zhí)行一個(gè)方法,于是這些方法被排隊(duì)在一個(gè)多帶帶的地方。這個(gè)地方被稱為執(zhí)行棧。
當(dāng)腳本第一次執(zhí)行的時(shí)候,js引擎會(huì)解析這段代碼,并將其中的同步代碼按照?qǐng)?zhí)行順序加入執(zhí)行棧中,然后從頭開始執(zhí)行。如果當(dāng)前執(zhí)行的是一個(gè)方法,那么js會(huì)向執(zhí)行棧中添加這個(gè)方法的執(zhí)行環(huán)境,然后進(jìn)入這個(gè)執(zhí)行環(huán)境繼續(xù)執(zhí)行其中的代碼。當(dāng)這個(gè)執(zhí)行環(huán)境中的代碼 執(zhí)行完畢并返回結(jié)果后,js會(huì)退出這個(gè)執(zhí)行環(huán)境并把這個(gè)執(zhí)行環(huán)境銷毀,回到上一個(gè)方法的執(zhí)行環(huán)境。這個(gè)過程反復(fù)進(jìn)行,直到執(zhí)行棧中的代碼全部執(zhí)行完畢。

宏任務(wù)(macro taks)與微任務(wù)(micro task)

在異步函數(shù)中,可以細(xì)分為兩種任務(wù),宏任務(wù)與微任務(wù)。
宏任務(wù)有以下幾種:
①I/O
②setTimeout
③setInterval
④setImmediate
⑤requestAnimationFrame

微任務(wù)有以下幾種:
①process.nextTick
②MutationObserver
③Promise.then catch finally

異步編程案例

當(dāng)異步函數(shù)中同時(shí)存在微任務(wù)和宏任務(wù)的時(shí)候,先執(zhí)行完微任務(wù),再執(zhí)行宏任務(wù)

總結(jié)

瀏覽器中的事件循環(huán)機(jī)制就是js在執(zhí)行代碼時(shí),由上至下遍歷,優(yōu)先執(zhí)行同步函數(shù),在遇到異步函數(shù)的時(shí)候,將該任務(wù)放置執(zhí)行棧;當(dāng)任務(wù)隊(duì)列中沒有同步函數(shù)之后便開始執(zhí)行執(zhí)行棧中的異步函數(shù),優(yōu)先執(zhí)行微任務(wù),后執(zhí)行宏任務(wù)。
js執(zhí)行順序: 同步函數(shù) -> 微任務(wù) -> 宏任務(wù)

思考題 setTimeout
console.log("script start")    
setTimeout(function(){
    console.log("settimeout")
})
console.log("script end")
    
// 輸出順序:script start->script end->settimeout

這個(gè)很簡(jiǎn)單,setTimeout中的語句會(huì)進(jìn)入宏任務(wù),后置執(zhí)行。

promise
console.log("script start")
let promise1 = new Promise(function (resolve) {
    console.log("promise1")
    resolve()
    console.log("promise1 end")
}).then(function () {
    console.log("promise2")
})
setTimeout(function(){
    console.log("settimeout")
})
console.log("script end")

// 輸出順序: script start->promise1->promise1 end->script end->promise2->settimeout

兩個(gè)要點(diǎn):
①promise中的then函數(shù)中代碼會(huì)進(jìn)入微任務(wù)
②promise中的resolve只是更改promise的狀態(tài),因此后面的語句會(huì)繼續(xù)執(zhí)行。

async/await
async function async1(){
   console.log("async1 start");
    await async2();
    console.log("async1 end")
}
async function async2(){
    console.log("async2")
}

console.log("script start");
async1();
console.log("script end")

// 輸出順序:script start->async1 start->async2->script end->async1 end

async函數(shù)表示函數(shù)里面可能會(huì)有異步方法,await后面跟一個(gè)表達(dá)式,async方法執(zhí)行時(shí),遇到await會(huì)立即執(zhí)行表達(dá)式,然后把表達(dá)式后面的代碼放到微任務(wù)隊(duì)列里,讓出執(zhí)行棧讓同步代碼先執(zhí)行

綜合測(cè)試
async function async1() {
    console.log("async1 start");
    await async2();
    console.log("async1 end");
}
async function async2() {
    console.log("async2");
}
console.log("script start");
setTimeout(function() {
    console.log("setTimeout");
}, 0)
async1();
new Promise(function(resolve) {
    console.log("promise1");
    resolve();
}).then(function() {
    console.log("promise2");
});
console.log("script end");

這題不公布答案,自行答題。

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

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

相關(guān)文章

  • 淺談不同環(huán)境下的JavaScript執(zhí)行機(jī)制 + 示例詳解

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

    wanghui 評(píng)論0 收藏0
  • 淺談 JavaScript 運(yùn)行機(jī)制

    摘要:以多線程的形式,允許單個(gè)任務(wù)分成不同的部分進(jìn)行運(yùn)行。提供協(xié)調(diào)機(jī)制,一方面防止進(jìn)程之間和線程之間產(chǎn)生沖突,另一方面允許進(jìn)程之間和線程之間共享資源。主線程會(huì)不斷的重復(fù)上訴過程。 眾所周知,js是單線程的,說到線程,我們首先來仔細(xì)辨析一下線程和進(jìn)程的知識(shí)。 一、進(jìn)程與線程 阮一峰老師的一篇文章寫的很好 cpu會(huì)給當(dāng)前進(jìn)程分配資源,進(jìn)程是資源分配的最小單位,進(jìn)程的資源會(huì)分配給線程使用,線程是C...

    URLOS 評(píng)論0 收藏0
  • 淺談對(duì)JavaScript閉包的理解

    摘要:關(guān)于循環(huán)和閉包當(dāng)循環(huán)和閉包結(jié)合在一起時(shí),經(jīng)常會(huì)產(chǎn)生讓初學(xué)者覺得匪夷所思的問題。閉包是一把雙刃劍是比較難以理解和掌握的部分,它十分強(qiáng)大,卻也有很大的缺陷,如何使用它完全取決于你自己。 在談閉包之前,我們首先要了解幾個(gè)概念: 什么是函數(shù)表達(dá)式? 與函數(shù)聲明有何不同? JavaScript查找標(biāo)識(shí)符的機(jī)制 JavaScript的作用域是詞法作用域 JavaScript的垃圾回收機(jī)制 先來...

    missonce 評(píng)論0 收藏0
  • 淺談瀏覽器多進(jìn)程與JS線程

    摘要:引言一直對(duì)瀏覽器的進(jìn)程線程的運(yùn)行一無所知,經(jīng)過一次的刷刷刷相關(guān)的博客之后,對(duì)其有了初步的了解,是時(shí)候該總結(jié)一波了。瀏覽器內(nèi)的進(jìn)程知道了進(jìn)程與線程之間的關(guān)系之后,下面是瀏覽器與進(jìn)程的關(guān)系了。 引言 一直對(duì)瀏覽器的進(jìn)程、線程的運(yùn)行一無所知,經(jīng)過一次的刷刷刷相關(guān)的博客之后,對(duì)其有了初步的了解,是時(shí)候該總結(jié)一波了。 進(jìn)程、線程之間的關(guān)系 一個(gè)進(jìn)程有一個(gè)或多個(gè)線程,線程之間共同完成進(jìn)程分配下來的...

    Juven 評(píng)論0 收藏0
  • 淺談React事件機(jī)制

    摘要:事件簡(jiǎn)介事件是合成事件,所有事件都自動(dòng)綁定到最外層上。支持事件的冒泡機(jī)制,我們可以使用和來中斷它。這樣做簡(jiǎn)化了事件處理和回收機(jī)制,效率也有很大提升。事件類型合成事件的事件類型是原生事件類型的一個(gè)子集。 React事件簡(jiǎn)介 React事件是合成事件,所有事件都自動(dòng)綁定到最外層上。因?yàn)閂irtual DOM 在內(nèi)存中是以對(duì)象的形式存在的,所以React 基于 Virtual DOM 實(shí)現(xiàn)了...

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

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

0條評(píng)論

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