衆所周知,js是一門單線程的語言。主要同他的用途有關,同一個時間只能作一件事兒,做爲瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操做DOM,這決定了它只能是單線程,不然會帶來很複雜的同步問題。java
因爲javaScript的資源加載是按序進行的,javaScript的單線程決定只有一個任務結束才能夠執行下一個任務,不然只能是下一個任務處於等待狀態。而任務分爲同步任務與異步任務:
同步任務:在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;
異步任務:不進入主線程、而進入"任務隊列"的任務,只有"任務隊列"通知主線程,某個異步任務能夠執行了,該任務纔會進入主線程執行;
一般咱們會將網頁的Dom渲染做爲同步任務,將獲取遠程數據,圖片加載等操做做爲異步任務進行。面試
promise.Trick() > promise的回調 > async > setTimeout > setInterval
promise
宏任務:包括總體代碼script,setTimeout,setInterval
微任務:Promise,process.nextTick瀏覽器
事件循環的順序決定js代碼的執行順序,進入總體代碼(宏任務)後,開始第一次循環。全部的同步任務先執行,根據任務類型部分異步任務進入入Event Queue,部分異步任務進入不一樣的Event Queue,宏任務的第一次循環結束後接着執行全部的微任務。而後再次從宏任務開始,找到其中一個任務隊列執行完畢,再執行全部的微任務。bash
console.log('start')
async function async1() {
console.log("async1");
await async2();
console.log("async1");
}
async function async2() {
console.log( 'async2');
}
console.log("script");
setTimeout(function () {
console.log("setTimeout");
},0);
async1();
new Promise(function () {
console.log("promise1");
}).then(function () {
console.log("promise2");
});
複製代碼
輸出:異步
start
script
async1
async2
promise1
promise2
async1
setTimeout
複製代碼
解析: 首先執行全部的同步任務,async與await搭配使用時是異步任務,async單獨定義函數時則當作同步任務執行,因此輸出start,script,遇到setTimeout將其放在入Event Queue任務隊列中,執行async1函數後 輸出async1,async2,此時要等待async2執行完畢,將其放在微任務的Event Queue中,因此此時主線程執行下面的代碼,new Promise實例會當即執行,輸出promise1,碰到then異步函數進入Event Queue任務隊列中,此時宏任務第一輪執行完畢,去執行全部的微任務,微任務執行結束後將宏任務的任務隊列的異步任務放在主線程進行執行。async