最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

單線程JavaScript為何如此高效

2023-07-05 13:39 作者:chaojilaji123  | 我要投稿

原文合集地址如下,有需要的朋友可以關(guān)注

本文地址

合集地址

什么是js執(zhí)行機(jī)制

JavaScript 的執(zhí)行機(jī)制指的是 JavaScript 代碼在運(yùn)行時(shí)的工作方式和順序。它涉及以下幾個(gè)關(guān)鍵概念:

  1. 單線程:JavaScript 是一門單線程的編程語(yǔ)言,意味著它只有一個(gè)主線程用于執(zhí)行代碼。這意味著 JavaScript 中的代碼是按順序執(zhí)行的,一次只能執(zhí)行一個(gè)任務(wù)。

  2. 任務(wù)隊(duì)列:JavaScript 通過任務(wù)隊(duì)列來管理要執(zhí)行的任務(wù)。任務(wù)隊(duì)列中存放著各種類型的任務(wù),包括同步任務(wù)和異步任務(wù)。

  3. 事件循環(huán):JavaScript 的事件循環(huán)是一個(gè)持續(xù)運(yùn)行的過程,它負(fù)責(zé)監(jiān)視任務(wù)隊(duì)列并選擇下一個(gè)要執(zhí)行的任務(wù)。事件循環(huán)不斷地從任務(wù)隊(duì)列中獲取任務(wù)并將其交給主線程執(zhí)行。

  4. 同步任務(wù)和異步任務(wù):同步任務(wù)是按照順序在主線程上執(zhí)行的任務(wù),執(zhí)行一個(gè)任務(wù)時(shí)會(huì)阻塞后續(xù)任務(wù)的執(zhí)行。異步任務(wù)是在主線程上注冊(cè)并在將來某個(gè)時(shí)間點(diǎn)執(zhí)行的任務(wù),執(zhí)行異步任務(wù)時(shí)不會(huì)阻塞后續(xù)任務(wù)的執(zhí)行。

  5. 微任務(wù)和宏任務(wù):JavaScript 中的任務(wù)可以分為微任務(wù)和宏任務(wù)。微任務(wù)是在當(dāng)前任務(wù)執(zhí)行完畢后立即執(zhí)行的任務(wù),它們使用微任務(wù)隊(duì)列進(jìn)行管理。而宏任務(wù)是在事件循環(huán)的下一輪中執(zhí)行的任務(wù),它們使用任務(wù)隊(duì)列進(jìn)行管理。

JavaScript 的執(zhí)行順序:

  1. 執(zhí)行同步任務(wù),將函數(shù)調(diào)用和變量分配到調(diào)用棧中按順序執(zhí)行。

  2. 遇到異步任務(wù),如定時(shí)器、事件監(jiān)聽等,將其注冊(cè)到任務(wù)隊(duì)列中,并繼續(xù)執(zhí)行后續(xù)的同步代碼。

  3. 當(dāng)同步代碼執(zhí)行完畢后,主線程會(huì)檢查微任務(wù)隊(duì)列,依次執(zhí)行隊(duì)列中的微任務(wù)。

  4. 執(zhí)行完微任務(wù)后,主線程會(huì)從任務(wù)隊(duì)列中取出一個(gè)宏任務(wù)執(zhí)行。

  5. 循環(huán)執(zhí)行步驟 3 和步驟 4,直至任務(wù)隊(duì)列和微任務(wù)隊(duì)列都為空。

需要注意的是,JavaScript 中的異步任務(wù)通常是通過回調(diào)函數(shù)、Promise、async/await 等機(jī)制來處理。通過合理使用異步任務(wù)和任務(wù)隊(duì)列,可以實(shí)現(xiàn)非阻塞的代碼執(zhí)行,提高代碼的性能和響應(yīng)能力。JavaScript 的執(zhí)行機(jī)制主要涉及以下幾個(gè)概念:調(diào)用棧、事件循環(huán)和任務(wù)隊(duì)列。文字有點(diǎn)單調(diào),看看下面的圖理解理解

讓我們通過一個(gè)例子來解釋這些概念。假設(shè)我們有以下代碼:

console.log("Script?start");

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

Promise.resolve().then(function()?{
??console.log("Promise");
});

console.log("Script?end");

這段代碼的執(zhí)行機(jī)制如下:

  1. 首先,開始執(zhí)行代碼,遇到第一行 console.log("Script start"),它會(huì)立即打印 "Script start"。

  2. 接下來,遇到 setTimeout,它是一個(gè)異步函數(shù),會(huì)被放入任務(wù)隊(duì)列中,并設(shè)置一個(gè)定時(shí)器。由于定時(shí)器時(shí)間為 0,所以不會(huì)立即執(zhí)行。

  3. 然后,遇到 Promise.resolve().then(),它會(huì)創(chuàng)建一個(gè) Promise 對(duì)象,并將 .then() 中的回調(diào)函數(shù)放入微任務(wù)隊(duì)列中。

  4. 繼續(xù)執(zhí)行下一行,打印 "Script end"。

  5. 此時(shí),主線程上的同步代碼執(zhí)行完畢,開始執(zhí)行微任務(wù)隊(duì)列中的任務(wù)。首先執(zhí)行 Promise 的回調(diào)函數(shù),打印 "Promise"。

  6. 接著,主線程開始執(zhí)行任務(wù)隊(duì)列中的任務(wù)。由于定時(shí)器時(shí)間到達(dá),setTimeout 的回調(diào)函數(shù)被放入任務(wù)隊(duì)列中。

  7. 最后,主線程執(zhí)行任務(wù)隊(duì)列中的任務(wù),打印 "setTimeout"。

綜上所述,JavaScript 的執(zhí)行機(jī)制遵循以下步驟:

  1. 執(zhí)行同步代碼,將函數(shù)調(diào)用和變量分配到調(diào)用棧中按順序執(zhí)行。

  2. 遇到異步操作,如定時(shí)器、事件監(jiān)聽等,將其注冊(cè)到任務(wù)隊(duì)列中,并繼續(xù)執(zhí)行后續(xù)的同步代碼。

  3. 同步代碼執(zhí)行完畢后,主線程會(huì)檢查微任務(wù)隊(duì)列,依次執(zhí)行隊(duì)列中的微任務(wù)(Promise 回調(diào)函數(shù))。

  4. 執(zhí)行完微任務(wù)后,主線程會(huì)從任務(wù)隊(duì)列中取出任務(wù)執(zhí)行,執(zhí)行完一個(gè)任務(wù)后再檢查微任務(wù)隊(duì)列,如此循環(huán),直至任務(wù)隊(duì)列為空。

需要注意的是,微任務(wù)優(yōu)先級(jí)高于任務(wù)隊(duì)列中的任務(wù),所以在執(zhí)行任務(wù)隊(duì)列中的任務(wù)之前,會(huì)先執(zhí)行完所有的微任務(wù)。

現(xiàn)學(xué)現(xiàn)用,再看一個(gè)例子:

????async?function?async1()?{
???console.log("async1?start");
???await?async2();
???console.log("async1?end");
????}
????async?function?async2()?{
????????console.log("async2");
????}
????console.log("js?start");
????setTimeout(function?()?{
??????console.log("timeout");
????},?0);
????async1();
????new?Promise(function?(resolve)?{
????????console.log("promise");
????????resolve();
????}).then(function?()?{
????????console.log("then");
????});
????console.log("js?end");

這段代碼的打印順序如下:

  1. "js start":立即打印,表示 JavaScript 代碼的開始執(zhí)行。

  2. "async1 start":由于 async1 函數(shù)被調(diào)用,所以會(huì)打印 "async1 start"。

  3. "async2":async1 函數(shù)中調(diào)用了 async2 函數(shù),因此會(huì)打印 "async2"。

  4. "promise":new Promise 的回調(diào)函數(shù)立即執(zhí)行,所以會(huì)打印 "promise"。

  5. "js end":立即打印,表示 JavaScript 代碼的執(zhí)行結(jié)束。

  6. "async1 end":由于 async2 函數(shù)是一個(gè)異步函數(shù),await async2() 表達(dá)式會(huì)等待 async2 函數(shù)執(zhí)行完畢,然后繼續(xù)執(zhí)行下面的代碼,所以會(huì)打印 "async1 end"。

  7. "then":Promisethen 方法是異步執(zhí)行的,所以會(huì)在下一個(gè)事件循環(huán)中執(zhí)行,因此會(huì)打印 "then"。

  8. "timeout":由于 setTimeout 的延遲時(shí)間為 0,所以會(huì)在下一個(gè)事件循環(huán)中執(zhí)行,因此會(huì)打印 "timeout"。 代碼的執(zhí)行順序是按照同步代碼的順序執(zhí)行,異步代碼則根據(jù)事件循環(huán)的機(jī)制來執(zhí)行。async/await 會(huì)暫停同步代碼的執(zhí)行,并等待異步操作完成后再繼續(xù)執(zhí)行后續(xù)的代碼。

總結(jié)

JS 代碼的執(zhí)行順序主要為:

  1. 同步代碼 同步代碼(sync code)直接進(jìn)入執(zhí)行棧執(zhí)行。執(zhí)行順序按代碼書寫順序。

  2. 異步任務(wù)回調(diào) 異步任務(wù)(如 setTimeout)進(jìn)入任務(wù)隊(duì)列。

  3. 事件循環(huán) 事件循環(huán)周期性地從任務(wù)隊(duì)列取出任務(wù),推入執(zhí)行棧執(zhí)行。當(dāng)執(zhí)行棧為空時(shí),才會(huì)取出隊(duì)列中的任務(wù)。

  4. 執(zhí)行棧先進(jìn)后出 執(zhí)行棧采用先進(jìn)后出的方式執(zhí)行函數(shù)。在函數(shù)執(zhí)行完畢后才會(huì)執(zhí)行上層函數(shù)。 這保證了函數(shù)的正確嵌套調(diào)用。

  5. 微任務(wù)優(yōu)先級(jí)高于宏任務(wù)

  • 宏任務(wù)(macrotask):出于任務(wù)隊(duì)列的任務(wù)。比如 setTimeout、setInterval。

  • 微任務(wù)(microtask):比如 Promise .then、MutationObserver 。 微任務(wù)的優(yōu)先級(jí)高于宏任務(wù)。 所以整個(gè)執(zhí)行順序可以描述為:

  1. 同步代碼按順序進(jìn)入執(zhí)行棧執(zhí)行

  2. 異步宏任務(wù)進(jìn)入任務(wù)隊(duì)列

  3. 當(dāng)執(zhí)行棧清空時(shí),執(zhí)行微任務(wù)

  4. 接著執(zhí)行宏任務(wù)

  5. 循環(huán)往復(fù)


單線程JavaScript為何如此高效的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
汪清县| 新干县| 会泽县| 福安市| 汤原县| 桃源县| 会东县| 江城| 桐梓县| 郎溪县| 惠州市| 阿克苏市| 通州市| 太谷县| 卓尼县| 四川省| 宣威市| 巴里| 延吉市| 屏山县| 惠东县| 成安县| 大厂| 乡城县| 周至县| 保山市| 许昌市| 防城港市| 巨野县| 台中县| 广南县| 砚山县| 白玉县| 昔阳县| 岗巴县| 罗甸县| 安丘市| 新干县| 恩施市| 民丰县| 古丈县|