亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

從JS引擎理解Await b()與Promise.then(b)的堆棧處理

ziwenxie / 3121人閱讀

摘要:對于引擎來說,兩者獲取堆棧的方式是不同的。對于引擎來說,堆棧信息附加在了函數(shù)所返回的并在鏈中傳遞,這樣函數(shù)也能在需要的時候獲取堆棧信息。使用可以實時監(jiān)控線上應(yīng)用的錯誤,并獲取完整的堆棧信息。

譯者按: Async/Await真的只是簡單的語法糖嗎?No!

原文:Asynchronous stack traces: why await beats .then()

作者: Mathias Bynens: Google V8引擎開發(fā)者

譯者:Fundebug

為了保證可讀性,本文采用意譯而非直譯。另外,本文版權(quán)歸原作者所有,翻譯僅用于學習。

與直接使用Promise相比,使用Async/Await不僅可以提高代碼的可讀性,同時也可以優(yōu)化JavaScript引擎的執(zhí)行方式。這篇博客將介紹Async/Await是如何優(yōu)化JavaScript引擎對堆棧信息的處理。

Async/Await與Promise最大區(qū)別在于:await b()會暫停所在的async函數(shù)的執(zhí)行;而Promise.then(b)將b函數(shù)加入回調(diào)鏈中之后,會繼續(xù)執(zhí)行當前函數(shù)。對于堆棧來說,這個不同點非常關(guān)鍵。

當一個Promise鏈拋出一個未處理的錯誤時,無論我們使用await b()還是Promise.then(b),JavaScript引擎都需要打印錯誤信息及其堆棧。對于JavaScript引擎來說,兩者獲取堆棧的方式是不同的。

Promise.then(b)

示例代碼中,函數(shù)c()會在異步函數(shù)b()成功resolve之后執(zhí)行:

const a = () => {
    b().then(() => c());
};

當調(diào)用a()函數(shù)時,這些事情同步發(fā)生:

b()函數(shù)被調(diào)用,它會返回一個Promise,這個Promise會在未來的某個時刻resolve。

.then()回調(diào)函數(shù)(實際調(diào)用了c()函數(shù))被添加到回調(diào)鏈。

這樣,a()函數(shù)內(nèi)的代碼就執(zhí)行完了。a()函數(shù)不會被暫停,因此在異步函數(shù)b()resolve時,a()函數(shù)的作用域已經(jīng)不存在了。假設(shè)b()或者c()拋出了一個錯誤,則堆棧信息中應(yīng)該包含a()函數(shù),因為它們都是在a()函數(shù)內(nèi)被調(diào)用。對a()函數(shù)的任何引用都不存在了,要如何生成包含a()的堆棧信息呢?

為了解決這個問題,JavaScript引擎需要做一些額外的工作:它會及時記錄并且保存堆棧信息。對于V8引擎來說,堆棧信息附加在了b()函數(shù)所返回的Promise并在Promise鏈中傳遞,這樣c()函數(shù)也能在需要的時候獲取堆棧信息。

記錄堆棧信息需要時間,這樣會降低性能;而保存堆棧信息需要占用額外的內(nèi)存。

使用Fundebug, 可以實時監(jiān)控線上應(yīng)用的錯誤,并獲取完整的堆棧信息。

Await b()

我們可以使用Async/Await實現(xiàn)同樣的代碼,同步函數(shù)c()會等到異步函數(shù)b()執(zhí)行結(jié)束之后再執(zhí)行:

const a = async () => {
    await b();
    c();
};

使用await時,無需存儲當前的堆棧信息,因為存儲b()到a()的指針就足夠了。當?shù)却齜()函數(shù)執(zhí)行時,a()函數(shù)被暫停了,因此a()函數(shù)的作用域還在內(nèi)存可以訪問。如果b()函數(shù)拋出一個錯誤,堆棧信息可以通過指針迅速生成。如果c()函數(shù)拋出一個錯誤,堆棧信息也可以像同步函數(shù)一樣生成,因為c()函數(shù)是在a()函數(shù)中執(zhí)行的。不論是b()還是c(),我們都不需要去存儲堆棧信息,因為堆棧信息可以在需要的時候立即生成。而存儲指針,顯然比存儲堆棧更加節(jié)省內(nèi)存。

建議

很多ECMAScript語法特性看起來都只是語法糖,其實并非如此,至少Async/Await絕不僅僅只是語法糖。

為了讓JavaScript引擎處理堆棧的方式性能更高并且更加節(jié)省內(nèi)存,請遵循這些建議:

使用Async/Await,而不是直接使用Promise

使用babel-preset-env,避免Babel不必要地轉(zhuǎn)換Async/Await

盡管V8引擎還沒有實現(xiàn)這些優(yōu)化,請遵循這些建議。當我們?yōu)閂8實現(xiàn)這些優(yōu)化的時候,你的程序可以保證最佳的性能。(作者是V8引擎的開發(fā)者)

一般來說,盡量不要去使用Babel轉(zhuǎn)碼器。所有支持Service Workers的瀏覽器都支持Async/Await,因此沒有必要去對Async/Await轉(zhuǎn)碼。這一點對于JavaScript modules via script tag同樣適用。關(guān)于這一點,大家可以參考Deploying ES2015+ Code in Production Today。

關(guān)于Fundebug

Fundebug專注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java實時BUG監(jiān)控。 自從2016年雙十一正式上線,F(xiàn)undebug累計處理了6億+錯誤事件,得到了Google、360、金山軟件等眾多知名用戶的認可。歡迎免費試用!

版權(quán)聲明

轉(zhuǎn)載時請注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2018/07/18/javascript-engine-await-promise/

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

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/96706.html

相關(guān)文章

  • JavaScript是如何工作:事件循環(huán)和異步編程崛起+ 5種使用 async/await

    摘要:事件循環(huán)從回調(diào)隊列中獲取并將其推入調(diào)用堆棧。執(zhí)行從調(diào)用堆棧中移除從調(diào)用堆棧中移除快速回顧值得注意的是,指定了事件循環(huán)應(yīng)該如何工作,這意味著在技術(shù)上它屬于引擎的職責范圍,不再僅僅扮演宿主環(huán)境的角色。 此篇是 JavaScript是如何工作的第四篇,其它三篇可以看這里: JavaScript是如何工作的:引擎,運行時和調(diào)用堆棧的概述! JavaScript是如何工作的:深入V8引擎&編寫...

    Honwhy 評論0 收藏0
  • JavaScript 工作原理之四-事件循環(huán)及異步編程出現(xiàn)和 5 種更好 async/await

    摘要:函數(shù)會在之后的某個時刻觸發(fā)事件定時器。事件循環(huán)中的這樣一次遍歷被稱為一個。執(zhí)行完畢并出棧。當定時器過期,宿主環(huán)境會把回調(diào)函數(shù)添加至事件循環(huán)隊列中,然后,在未來的某個取出并執(zhí)行該事件。 原文請查閱這里,略有改動。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第四章。 現(xiàn)在,我們將會通過回顧單線程環(huán)境下編程的弊端及如何克服這些困難以創(chuàng)建令人驚嘆...

    maochunguang 評論0 收藏0
  • 前端面試題 -- JavaScript(二)

    摘要:拋出的錯誤對象會被方法回調(diào)函數(shù)接收到命令命令后面是一個對象,返回該對象的結(jié)果。有人將其稱之為宏任務(wù)微任務(wù),定時器就屬于宏任務(wù)的范疇。 前言 上一篇 前端面試題-JavaScript(一), 感興趣的小伙伴也可以移步這里查看 完整版JavaScript面試題,面試題會不定期更新加進去一些個人工作中遇到的或者認為比較重要的東西,后面會涉及到前端的各個方面,感興趣的小伙伴可以關(guān)注哦! 如果文...

    cgspine 評論0 收藏0
  • 最后一次搞懂 Event Loop

    摘要:由于是單線程的,這些方法就會按順序被排列在一個單獨的地方,這個地方就是所謂執(zhí)行棧。事件隊列每次僅執(zhí)行一個任務(wù),在該任務(wù)執(zhí)行完畢之后,再執(zhí)行下一個任務(wù)。 Event Loop 是 JavaScript 異步編程的核心思想,也是前端進階必須跨越的一關(guān)。同時,它又是面試的必考點,特別是在 Promise 出現(xiàn)之后,各種各樣的面試題層出不窮,花樣百出。這篇文章從現(xiàn)實生活中的例子入手,讓你徹底理解 E...

    gself 評論0 收藏0

發(fā)表評論

0條評論

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