關於js中事件循環、同步異步、宏任務和微任務存在的時候函數執行順序的簡單理解

講述目的:本文章針對JS萌新,是要用最簡單的解釋讓讀者可以判斷在函數語句的執行順序,不涉及關於js更深層的理解和探討也不花費精力講解js爲何會將執行任務有這些區分,只討論任務的執行順序,保護讀者不被各類概念繞暈,大神可繞道。ajax

講述思路promise

1.簡單理解同步異步、宏任務和微任務異步

2.執行順序判斷方法函數

3.簡單實例分析spa

4.稍複雜點的實例分析線程

正文開始code

1.簡單理解同步異步、宏任務和微任務blog

js是單線程的,全部的任務都要排隊挨個執行,就比如作保健(執行js代碼),保健師傅只有一個(單線程),顧客(js代碼)需排隊享受服務,排隊的順序按照顧客的種類(同步異步、宏任務微任務)和顧客到店順序(在代碼中的位置)執行;隊列

同步與異步、宏任務和微任務分別是函數兩個不一樣維度的描述。事件

異步任務:setTimeout和setInterval、ajax、事件綁定等

同步任務:除了異步任務外的全部任務

微任務:process.nextTick和 Promise後的theny語句和catch語句等

宏任務:除了微任務之外的全部任務 

2.執行順序判斷方法

先同步再異步,在此基礎上先宏任務再微任務

3.簡單實例分析

 1 setTimeout(function () {
 2 new Promise(function (resolve, reject) {
 3 console.log('異步宏任務promise');
 4 resolve();
 5 }).then(function () {
 6 console.log('異步微任務then')
 7 })
 8 console.log('異步宏任務');
 9 }, 0)
10 new Promise(function (resolve, reject) {
11 console.log('同步宏任務promise');
12 resolve();
13 }).then(function () {
14 console.log('同步微任務then')
15 })
16 console.log('同步宏任務')

 

結果

 

分析:setTimeout是異步任務,雖然他在0秒後執行但仍排在隊列的後面,所以其中的代碼所有靠後執行;new Promise是同步任務同時也是主任務,所以第一行先打印'同步宏任務promise',then是微任務因此靠後執行,先執行第16行代碼,以後再執行第13行的then語句,所以第二行輸出爲'同步宏任務',第三行爲'同步微任務then';接下來執行setTimeout中的語句,then由於是微任務因此在第8行執行完成後再執行。

 4.稍複雜點的實例分析

 1     setTimeout(() => {
 2         console.log('異步1任務time1');
 3         new Promise(function (resolve, reject) {
 4             console.log('異步1宏任務promise');
 5             setTimeout(() => {
 6                 console.log('異步1任務time2');
 7             }, 0);
 8             resolve();
 9         }).then(function () {
10             console.log('異步1微任務then')
11         })
12     }, 0);
13     console.log('主線程宏任務');
14     setTimeout(() => {
15         console.log('異步2任務time2');
16 
17     }, 0);
18     new Promise(function (resolve, reject) {
19         console.log('宏任務promise');
20         // reject();
21         resolve();
22     }).then(function () {
23         console.log('微任務then')
24     }).catch(function () {
25         console.log('微任務catch')
26     })
27     console.log('主線程宏任務2');

本例中需注意第9行的then是在第14行的setTimeout以前執行的,而第5行的setTimeout在第14行以後執行。也就是在一個異步任務代碼塊中,會先執行完全部同步語句(包括宏任務和微任務),而後去執行整個代碼中的同級別的異步任務,而第5行的setTimeout因是第二層異步語句,會被放到以後才執行。

執行結果爲

相關文章
相關標籤/搜索