成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

「今日頭條」前端面試題和思路解析

寵來也 / 1923人閱讀

摘要:一篇文章和一道面試題最近,有篇名為張圖幫你一步步看清和的執(zhí)行順序的文章引起了我的關注。作者用一道年今日頭條的前端面試題為引子,分步講解了最終結果的執(zhí)行原因。從字面意思理解,讓我們等等。當前的最新版本,在這里的執(zhí)行順序上,的確存在有問題。

一篇文章和一道面試題

最近,有篇名為 《8張圖幫你一步步看清 async/await 和 promise 的執(zhí)行順序》 的文章引起了我的關注。

作者用一道2017年「今日頭條」的前端面試題為引子,分步講解了最終結果的執(zhí)行原因。其中涉及到了不少概念,比如異步的執(zhí)行順序,宏任務,微任務等等,同時作者限定了執(zhí)行范圍,以瀏覽器的 event loop 機制為準。下面是原題的代碼:

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");

緊接著,作者先給出了答案。并希望讀者先行自我測試。

script start
async1 start
async2
promise1
script end
promise2
async1 end
setTimeout

我在看這道題的時候,先按照自己的理解寫出了結果。

script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
一些重要的概念

這里需要先簡單地說一些 event loop 的概念。

Javascript是單線程的,所有的同步任務都會在主線程中執(zhí)行。

主線程之外,還有一個任務隊列。每當一個異步任務有結果了,就往任務隊列里塞一個事件。

當主線程中的任務,都執(zhí)行完之后,系統(tǒng)會 “依次” 讀取任務隊列里的事件。與之相對應的異步任務進入主線程,開始執(zhí)行。

異步任務之間,會存在差異,所以它們執(zhí)行的優(yōu)先級也會有區(qū)別。大致分為 微任務(micro task,如:Promise、MutaionObserver等)和宏任務(macro task,如:setTimeout、setInterval、I/O等)。同一次事件循環(huán)中,微任務永遠在宏任務之前執(zhí)行。

主線程會不斷重復上面的步驟,直到執(zhí)行完所有任務。

另外,還有 async/await 的概念。

async 函數(shù),可以理解為是Generator 函數(shù)的語法糖。

它建立在promise之上,總是與await一起使用的。

await會返回一個Promise 對象,或者一個表達式的值。

其目的是為了讓異步操作更優(yōu)雅,能像同步一樣地書寫。

我的理解

再說說我對這道題的理解。

首先,從console的數(shù)量上看,會輸出8行結果。

再瞟了一眼代碼,看到了setTimeout,于是,默默地把它填入第8行。

在setTimeout附近,看到了 console.log( "script start" ) 和 async1(),可以確認它們是同步任務,會先在主線程中執(zhí)行。所以,妥妥地在第1行填入 script start,第2行填入async1方法中的第一行 async1 start。

接下來,遇到了await。從字面意思理解,讓我們等等。需要等待async2()函數(shù)的返回,同時會阻塞后面的代碼。所以,第3行填入 async2。

講道理,await都執(zhí)行完了,該輪到console.log( "async1 end" )的輸出了。但是,別忘了下面還有個Promise,有一點需要注意的是:當 new 一個 Promise的時候,其 resolve 方法中的代碼會立即執(zhí)行。如果不是 async1()的 await 橫插一杠,promise1 可以排得更前面。所以,現(xiàn)在第4行填入 promise1。

再接下來,同步任務 console.log( "script end" ) 執(zhí)行。第5行填入 script end。

還有第6和第7行,未填?;仡櫼幌律厦嫣岬?async/await 的概念,其目的是為了讓異步能像同步一樣地書寫。那么,我認為 console.log( "async1 end" ) 就是個同步任務。所以,第6行填入async1 end。

最后,順理成章地在第7行填入 promise2。

與作者答案的不同

回過頭對比與作者的答案,發(fā)現(xiàn)第6和第7行的順序有問題。

再耐心地往下看文章,反復地看了幾遍 async1 end 和 promise2 誰先誰后,還是無法理解為何在chrome瀏覽器中,promise2 會先于 async1 end 輸出。

然后,看到評論區(qū),發(fā)現(xiàn)也有人提出了相同的疑惑。@rhinel提出,在他的72.0.3622.0(正式版本)dev(64 位)的chrome中,跑出來的結果是 async1 end 在 promise2 之前。

隨即我想到了一種可能,JS的規(guī)范可能會在未來有變化。于是,我用自己的react工程試了一下(工程中的babel-loader版本為7.1.5。.babelrc的presets設置了stage-3),結果與我的理解一致。當前的最新版本 chromeV71,在這里的執(zhí)行順序上,的確存在有問題。

于是,我也在評論區(qū)給作者留了言,進行了討論。@rhinel最后也證實,其實最近才發(fā)布通過了這個順序的改進方案,這篇 《Faster async functions and promises》 詳細解釋了這個改進,以及實現(xiàn)效果。不久之后,作者也在他文章的最后,補充了我們討論的結果,供讀者參考。

總結

最后,我想說的是,本文雖然只是由一道面試題引申出的,對瀏覽器執(zhí)行順序的思考、討論與驗證的過程。但正是因為有了這些過程,才讓更多的思想得以碰撞,概念進一步得以理解,規(guī)范得以明了。

有機會的話,希望能有與更多的同道,多多交流。

更新

講道理,async/await 已經出來挺久了,但在近期的面試中,凡是問及異步操作,面試者的回答都還是 Promise,甚至知道 async/await 都很少,看來還有待進一步普及。并不是說 Promise 有什么不好,只是覺得 async/await 用著挺爽的,希望能有更多的人用吧。只有用了,才能進一步理解,產生更多的思考。

所以,這兩天翻出了之前寫的關于什么是async函數(shù),及其相較于 Promise 的優(yōu)勢。重新整理了一下,原文請前往《細說async/await相較于Promise的優(yōu)勢》。

希望對你有幫助,也期待進一步的交流,感謝!

PS:歡迎關注我的公眾號 “超哥前端小棧”,交流更多的想法與技術。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/100308.html

相關文章

  • 從簡歷被拒到收割今日頭條 offer,我用一年時間破繭成蝶!

    摘要:正如我標題所說,簡歷被拒??戳宋液啔v之后說頭條競爭激烈,我背景不夠,點到為止。。三準備面試其實從三月份投遞簡歷開始準備面試到四月份收,也不過個月的時間,但這都是建立在我過去一年的積累啊。 本文是 無精瘋 同學投稿的面試經歷 關注微信公眾號:進擊的java程序員K,即可獲取最新BAT面試資料一份 在此感謝 無精瘋 同學的分享 目錄: 印象中的頭條 面試背景 準備面試 ...

    tracymac7 評論0 收藏0
  • 從簡歷被拒到收割今日頭條 offer,我用一年時間破繭成蝶!

    摘要:正如我標題所說,簡歷被拒。看了我簡歷之后說頭條競爭激烈,我背景不夠,點到為止。。三準備面試其實從三月份投遞簡歷開始準備面試到四月份收,也不過個月的時間,但這都是建立在我過去一年的積累啊。 本文是 無精瘋 同學投稿的面試經歷 關注微信公眾號:進擊的java程序員K,即可獲取最新BAT面試資料一份 在此感謝 無精瘋 同學的分享目錄:印象中的頭條面試背景準備面試頭條一面(Java+項目)頭條...

    wdzgege 評論0 收藏0
  • 前端面試題系列5」ES6 中箭頭函數(shù)的用法

    摘要:在這里,如果用箭頭函數(shù),可以這樣改寫箭頭函數(shù)并沒有自己的,所以事件處理函數(shù)的調用者并不受影響。比如,在需要動態(tài)上下文的場景中,使用箭頭函數(shù)需要格外地小心,這些場景包括對象的方法原型方法事件的回調構造函數(shù)。 showImg(https://segmentfault.com/img/bVboce6?w=1304&h=734); 前言 年味兒漸散,收拾下心情,繼續(xù)敲代碼吧。 對于即將到來金三...

    betacat 評論0 收藏0
  • 令人費解的 async/await 執(zhí)行順序

    摘要:問題的關鍵在于其執(zhí)行過程中的微任務數(shù)量,下文中我們需要用上述代碼中的方式對微任務的執(zhí)行順序進行標記,以輔助我們理解這其中的執(zhí)行過程。 原文發(fā)布在掘金社區(qū):https://juejin.im/post/5c3cc981f265da616a47e028 起源 2019年了,相信大家對 Promise 和 async/await 都不再陌生了。 前幾日,我在社區(qū)讀到了一篇關于 async/...

    WilsonLiu95 評論0 收藏0
  • 前端面試題系列4」this的原理以及用法

    摘要:但是有一個總的原則那就是總會指向,調用函數(shù)的那個對象。作為對象方法的調用函數(shù)作為某個對象的方法調用,這時就指這個上級對象。 showImg(https://segmentfault.com/img/bVbnvF7?w=750&h=422); 這是前端面試題系列的第 4 篇,你可能錯過了前面的篇章,可以在這里找到: 偽類與偽元素的區(qū)別及實戰(zhàn) 如何實現(xiàn)一個圣杯布局? 今日頭條 面試題和思...

    fnngj 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<