成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳談JavaScript 中的微任務和宏任務

開發 前端
在 JavaScript 引擎中,任務分為兩種類型:微任務(microtask)和宏任務(macrotask)。 微任務是指在當前任務執行結束后立即執行的任務,它可以看作是在當前任務的“尾巴”添加的任務。

js中什么是微任務和宏任務

在 JavaScript 引擎中,任務分為兩種類型:微任務(microtask)和宏任務(macrotask)。 微任務是指在當前任務執行結束后立即執行的任務,它可以看作是在當前任務的“尾巴”添加的任務。常見的微任務包括 Promise 回調和 process.nextTick。 宏任務是指需要排隊等待 JavaScript 引擎空閑時才能執行的任務。常見的宏任務包括 setTimeout、setInterval、I/O 操作、DOM 事件等。 JavaScript 引擎會先執行當前任務中的所有微任務,然后再執行宏任務隊列中的第一個任務。這個過程會不斷重復,直到宏任務隊列中的任務被全部執行完畢。

JS為什么要區分微任務和宏任務

JavaScript 之所以要區分微任務和宏任務,是因為微任務和宏任務的執行順序不同,這對 Web 開發中一些異步操作的實現有著重要的影響。 在 JavaScript 中,微任務會優先于宏任務執行。這意味著在當前任務執行結束后,所有微任務都會被立即執行,而宏任務只有在所有微任務執行完畢后才會執行。這種執行順序保證了微任務的優先級,可以避免一些問題的出現,比如處理 Promise 對象時可能會出現的競態條件。 舉個例子,當我們使用 Promise 對象時,它會返回一個 Promise 實例并將回調函數放入微任務隊列中。當 Promise 的狀態發生改變時,它會立即執行微任務隊列中的回調函數,而不是等待當前任務結束后再執行。這種特性可以保證 Promise 回調函數的執行順序,避免出現競態條件,從而使代碼更加可靠。 另一方面,宏任務的執行是在當前任務結束后才會執行的,這意味著可以將一些耗時的操作放入宏任務隊列中,從而避免阻塞當前任務的執行。比如,我們可以將一些需要等待一段時間才能執行的代碼放入 setTimeout 的回調函數中,這樣可以使頁面在執行這些代碼的同時仍然保持響應,提高用戶體驗。 因此,JavaScript 之所以要區分微任務和宏任務,是為了保證異步操作的正確性和性能。

JS中微任務和宏任務執行順序

  1. 首先執行當前代碼(同步任務),直到遇到第一個宏任務或微任務。
  2. 如果遇到微任務,則將它添加到微任務隊列中,繼續執行同步任務。
  3. 如果遇到宏任務,則將它添加到宏任務隊列中,繼續執行同步任務。
  4. 當前任務執行完畢后,JavaScript 引擎會先執行所有微任務隊列中的任務,直到微任務隊列為空。
  5. 然后執行宏任務隊列中的第一個任務,直到宏任務隊列為空。
  6. 重復步驟 4 和步驟 5,直到所有任務都被執行完畢。 需要注意的是,微任務比宏任務優先級要高,因此在同一個任務中,如果既有微任務又有宏任務,那么微任務會先執行完畢。而在不同的任務中,宏任務的執行優先級要高于微任務,因此在一個宏任務執行完畢后,它才會執行下一個宏任務和微任務隊列中的任務。 舉個例子,假設當前代碼中有一個 setTimeout 和一個 Promise,它們分別對應一個宏任務和一個微任務。那么執行順序如下:
    1). 執行當前代碼,將 setTimeout 和 Promise 添加到宏任務和微任務隊列中。
    2). 當前任務執行完畢,JavaScript 引擎先執行微任務隊列中的 Promise 回調函數。
    3). 微任務隊列為空后,再執行宏任務隊列中的 setTimeout 回調函數。 需要注意的是,在一些特殊情況下,微任務和宏任務的執行順序可能會發生變化,比如在使用 MutationObserver 監聽 DOM 變化時,它會被視為一個微任務,但是它的執行順序可能會比其他微任務更靠后。因此,需要根據具體情況來理解和處理微任務和宏任務的執行順序。

js微任務和宏任務有哪些

微任務:Promise 回調函數、process.nextTick、Object.observe(已廢棄)、MutationObserver。
宏任務:setTimeout、setInterval、setImmediate(Node.js 獨有)、requestAnimationFrame、I/O 操作、UI 渲染。

需要注意的是,不同的 JavaScript 引擎可能會存在一些差異,有些任務可能既可以作為微任務,也可以作為宏任務,比如在一些瀏覽器中,使用 MutationObserver 監聽 DOM 變化時,它會被視為一個微任務,但是在一些 Node.js 版本中,它會被視為一個宏任務。 另外,需要注意的是,Promise 回調函數是微任務,但是它的內部代碼可能會包含其他的異步操作,這些異步操作可能是微任務或宏任務,因此在處理 Promise 時需要考慮到它內部可能包含的其他異步操作。

案例

1.微任務:Promise 回調函數,宏任務:setTimeout 回調函數

console.log('start');setTimeout(() => console.log('setTimeout'), 0);Promise.resolve().then(() => console.log('Promise'));console.log('end');// start// end// Promise// setTimeout

解析: 首先輸出 start,然后通過 setTimeout 方法注冊了一個回調函數,它會被添加到宏任務隊列中。接著創建了一個 Promise 實例,并且通過 then 方法注冊了一個回調函數,在 Promise 對象的狀態改變時會執行這個回調函數。接著輸出 end。因為 Promise 回調函數是微任務,所以它會被添加到微任務隊列中,等待執行。等到主線程的同步任務執行完畢后,JavaScript 引擎會先執行微任務隊列中的任務,輸出 Promise,然后執行宏任務隊列中的任務,輸出 setTimeout。

2.微任務:process.nextTick 回調函數,宏任務:setImmediate 回調函數

console.log('start');setImmediate(() => console.log('setImmediate'));process.nextTick(() => console.log('process.nextTick'));console.log('end');// start// end// process.nextTick// setImmediate

解析: 在 Node.js 環境中,process.nextTick 回調函數是排在微任務隊列最前面的,優先級比 Promise 回調函數還要高。而 setImmediate 回調函數是排在宏任務隊列最后面的。所以,以上代碼會先輸出 start,然后輸出 end。等到主線程的同步任務執行完畢后,JavaScript 引擎會先執行微任務隊列中的任務,輸出 process.nextTick,然后執行宏任務隊列中的任務,輸出 setImmediate。

3.微任務:Promise 回調函數,宏任務:requestAnimationFrame 回調函數

console.log('start');requestAnimationFrame(() => console.log('requestAnimationFrame'));Promise.resolve().then(() => console.log('Promise'));console.log('end');// start// end// Promise// requestAnimationFrame

解析: 首先輸出 start,然后通過 requestAnimationFrame 方法注冊了一個回調函數,它會被添加到宏任務隊列中。接著創建了一個 Promise 實例,并且通過 then 方法注冊了一個回調函數,在 Promise 對象的狀態改變時會執行這個回調函數。接著輸出 end。因為 Promise 回調函數是微任務,所以它會被添加到微任務隊列中,等待執行。等到主線程的同步任務執行完畢后,JavaScript 引擎會先執行微任務隊列中的任務,輸出 Promise,然后執行宏任務隊列中的任務,輸出 requestAnimationFrame。

4.微任務:Promise 回調函數,宏任務:XMLHttpRequest 回調函數

console.log('start');const xhr = new XMLHttpRequest();xhr.open('GET', 'https://jsonplaceholder.typicode.com/users/1');xhr.onload = () => console.log('XMLHttpRequest');xhr.send();Promise.resolve().then(() => console.log('Promise'));console.log('end');// start// end// Promise// XMLHttpRequest

解析: 首先輸出 start,然后創建了一個 XMLHttpRequest 對象,并且通過 open 方法和 send 方法發送了一個 GET 請求。接著通過 onload 方法注冊了一個回調函數,在請求成功后會執行這個回調函數。接著創建了一個 Promise 實例,并且通過 then 方法注冊了一個回調函數,在 Promise 對象的狀態改變時會執行這個回調函數。接著輸出 end。因為 Promise 回調函數是微任務,所以它會被添加到微任務隊列中,等待執行。等到主線程的同步任務執行完畢后,JavaScript 引擎會先執行微任務隊列中的任務,輸出 Promise,然后等待 XMLHttpRequest 對象的回調函數執行。當請求成功后,JavaScript 引擎會執行宏任務隊列中的任務,輸出 XMLHttpRequest。

責任編輯:華軒 來源: 今日頭條
相關推薦

2020-12-29 08:21:03

JavaScript微任務宏任務

2022-06-13 10:24:47

宏任務微任務前端

2021-08-03 07:40:47

宏任務微任務React

2021-07-24 11:15:19

開發技能代碼

2021-01-18 08:24:51

JavaScriptMicrotask微任務

2021-08-17 09:55:05

JavaScript MicrotaskPromise

2024-10-23 16:02:40

JavaScriptPromiserejection

2013-12-17 10:15:19

OpenMP任務調度

2021-04-16 13:20:41

ZeitLinux工具

2011-06-16 16:20:32

JavaScript分解任務

2023-11-13 07:37:36

JS面試題線程

2021-12-04 22:05:41

網頁任務 Performanc

2021-02-02 11:02:20

React任務饑餓行為優先級任務

2011-06-08 13:50:39

C#類型轉換

2018-09-18 09:00:00

前端WebJavaScript

2012-04-20 14:44:11

JavaScript

2022-10-20 17:40:47

GroovyJuelJava

2009-06-25 14:41:06

JavaBean

2009-06-11 17:52:08

JavaBean

2023-11-10 08:14:40

推薦算法推薦系統
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久www成人免费无遮挡大片 | 欧美二区在线 | 黄色片亚洲 | 日韩免费视频 | 成人欧美一区二区三区黑人孕妇 | 欧美视频二区 | 日本黄色一级视频 | 久久99精品国产自在现线小黄鸭 | www.国产 | 日本高清视频在线播放 | 一区二区三区视频在线观看 | 精品久久久久久久久久 | 日韩高清一区 | 欧美视频成人 | 欧美在线a | h免费观看| 九九热在线视频观看这里只有精品 | 97超在线视频 | 亚洲欧美日韩中文在线 | 99精品视频在线观看 | 欧美激情在线播放 | 欧美精品在线视频 | 日本中文字幕在线观看 | 一区二区三区四区不卡 | 国产精品.xx视频.xxtv | 亚洲一区精品在线 | www.av在线| 精品99久久久久久 | 欧洲高清转码区一二区 | 美日韩精品| 国产主播第一页 | 久久99精品久久 | 亚洲一在线 | 日日av| 一区二区在线 | 在线天堂免费中文字幕视频 | 久久中文字幕视频 | 久久av一区二区三区 | 欧美高清视频在线观看 | 亚洲一区二区三区视频 | www.天堂av.com|