一道經典的前端筆試題,你能一眼寫出他們的執行結果嗎?前端
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');
首先第一個問題: JavaScript運行機制是什麼?ajax
詳細可參考:https://baijiahao.baidu.com/s?id=1615713540466951098&wfr=spider&for=pc編程
總結幾點就是:segmentfault
第二個問題:Promise的原理和運行機制是什麼?promise
古人云:「君子一言既出;駟馬難追」,這種「承諾未來會執行」的對象在JavaScript中稱爲Promise對象。異步
Promise 是異步編程的一種解決方案,實際上是一個構造函數,本身身上有all、reject、resolve這幾個方法,原型上有then、catch等方法。async
參考:http://www.javashuo.com/article/p-fydjigyf-ca.htmlide
這裏擴展一個問題:什麼是異步呢?異步編程
同步
就是一件事一件事的執行。只有前一個任務執行完畢,才能執行後一個任務。函數
js代碼只能一行一行的執行,不能在同一時間執行多個js代碼任務,這就致使若是有一段耗時較長的計算,或者是一個ajax請求等IO操做,若是沒有異步的存在,就會出現用戶長時間等待,而且因爲當前任務還未完成,因此這時候全部的其餘操做都會無響應,這時候就須要異步任務。
參考:http://www.javashuo.com/article/p-wkwacora-du.html
Promise運行順序總結:
第三個問題:async、await執行順序?
使用 async 定義的函數,當它被調用時,它返回的實際上是一個 Promise 對象。(當這個 async 函數返回一個值時,Promise 的 resolve 方法會負責傳遞這個值;當 async 函數拋出異常時,Promise 的 reject 方法也會傳遞這個異常值。)
await是一個讓出線程的標誌。await後面的函數會先執行一遍,而後就會跳出整個async函數來執行後面js棧的代碼,等本輪事件循環執行完了以後又會跳回到async函數中等待await後面表達式的返回值,若是返回值爲非promise則繼續執行async函數後面的代碼,不然將返回的promise放入promise隊列。
參考:http://www.javashuo.com/article/p-pqnsofgj-ek.html
問題四:setTimeout的執行?
setTimeout和Promise同樣也是異步的
宏任務通常包括:總體代碼script,setTimeout,setInterval。
微任務:Promise,process.nextTick
微任務執行優先級高於宏任務,因此Promise比setTimeout優先執行。
理解了以上4個問題,那麼這道筆試題也就容易理解了
最終結果: