最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS異步堆棧追蹤之為什么await勝過Promise

 更新時間:2021年04月28日 14:18:58   作者:淺笑·  
與直接使用Promise相比,使用async/await不僅可以使代碼更具可讀性,而且還可以在JavaScript引擎中實現(xiàn)一些有趣的優(yōu)化。這篇文章是關(guān)于一個這樣的優(yōu)化,涉及異步代碼的堆棧追蹤。

概述

async/await和Promise的根本區(qū)別在于await fn()暫停當(dāng)前函數(shù)的執(zhí)行,而promise.then(fn)在將fn調(diào)用添加到回調(diào)鏈后,繼續(xù)執(zhí)行當(dāng)前函數(shù)。

const fn = () => console.log('hello')
const a = async () => {
  await fn() // 暫停 fn 的執(zhí)行
}
// 調(diào)用 a 時,才恢復(fù) fn 的執(zhí)行
a() // "hello"

const promise = Promise.resolve()
// 將 fn 添加到回調(diào)鏈后,繼續(xù)執(zhí)行 fn
promise.then(fn) // "hello"

在堆棧追蹤的上下文中,這種差異非常顯著。

當(dāng)一個Promise鏈(無論是否脫糖化)在任何時候拋出一個未經(jīng)處理的異常時,JavaScript引擎都會顯示一條錯誤信息和(希望)記錄一個有用的堆棧追蹤。

作為一名開發(fā)人員,無論您使用的是普通的Promise還是async await,您都會期望這樣。

Promise

想象一個場景,當(dāng)對異步函數(shù)b的調(diào)用解析時,調(diào)用函數(shù)c:

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

當(dāng)調(diào)用a時,將同步發(fā)生以下情況:

  • b被調(diào)用并返回一個Promise,該P(yáng)romise將在將來某個時刻解決。
  • .then回調(diào)(實際上是調(diào)用c())被添加到回調(diào)鏈中( V8 術(shù)語中,[…]被添加為解析處理程序)。

之后,我們完成了在函數(shù)a的主體中執(zhí)行代碼。a永遠(yuǎn)不會被掛起,當(dāng)對b的異步調(diào)用解析時,上下文已經(jīng)消失了。

想象一下如果b(或c)異步拋出異常會發(fā)生什么?理想情況下,堆棧追蹤應(yīng)該包括a,因為b(或c)是從那里調(diào)用的,對吧?既然我們不在參考a了 ,那怎樣能做到呢?

為了讓它工作,JavaScript 引擎需要在上面的步驟之外做一些事情:它在有機(jī)會的時候捕獲并存儲堆棧追蹤。

在V8中,堆棧追蹤附加到b返回的Promise。當(dāng)Promise實現(xiàn)時,堆棧追蹤將被傳遞,以便c可以根據(jù)需要使用它。

b()[a] -> b().then()[a] -> c[a?:a]

捕獲堆棧追蹤需要時間(即降低性能);存儲這些堆棧追蹤需要內(nèi)存。

async/await

下面是同樣的程序,使用async/await而不是Promise編寫:

const b = () => Promise.resolve()
const a = async () => {
  await b()
  c()
}

使用await,即使在await調(diào)用中不收集堆棧追蹤,我們也可以恢復(fù)調(diào)用鏈。

這是可能的,因為a被掛起,正在等待b解決。如果b拋出異常,則可以按需以這種方式重建堆棧追蹤。

如果c拋出異常,堆棧追蹤可以像同步函數(shù)那樣構(gòu)造,因為發(fā)生這種情況時,我們?nèi)栽赼上下文中。

通過遵循以下建議,使 JavaScript 引擎能夠以更高效的方式處理堆棧追蹤:

  • 偏好async/await勝過Promise。
  • 使用 @babel/preset env避免不必要的async/await傳輸。

以上就是JS異步堆棧追蹤之為什么await勝過Promise的詳細(xì)內(nèi)容,更多關(guān)于Javascript的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 推薦10 款 SVG 動畫的 JavaScript 庫

    推薦10 款 SVG 動畫的 JavaScript 庫

    這篇文章主要推薦了10 款 SVG 動畫的 JavaScript 庫,非常的實用,效果也非常棒,有需要的朋友可以參考下。
    2015-03-03
  • 通過V8源碼看一個關(guān)于JS數(shù)組排序的詭異問題

    通過V8源碼看一個關(guān)于JS數(shù)組排序的詭異問題

    一直在學(xué)習(xí)C++,也想閱讀點(diǎn)開源的C++項目,發(fā)現(xiàn)網(wǎng)上對Google V8評價不錯,于是上Github上找到了源代碼,但在學(xué)習(xí)中遇到一個js數(shù)組排序的問題,下面這篇文章主要給大家介紹了通過V8源碼說說一個關(guān)于JS數(shù)組排序的詭異問題的相關(guān)資料,需要的朋友可以參考下。
    2017-08-08
  • JS獲取當(dāng)前網(wǎng)頁大小以及屏幕分辨率等

    JS獲取當(dāng)前網(wǎng)頁大小以及屏幕分辨率等

    這篇文章主要介紹了JS獲取當(dāng)前網(wǎng)頁大小以及屏幕分辨率等,方法雖簡單,但比較實用,需要的朋友可以參考下
    2014-09-09
  • 微信小程序局部刷新觸發(fā)整頁刷新效果的實現(xiàn)代碼

    微信小程序局部刷新觸發(fā)整頁刷新效果的實現(xiàn)代碼

    這篇文章主要介紹了微信小程序局部刷新觸發(fā)整頁刷新效果的實現(xiàn)代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-11-11
  • 移動端網(wǎng)頁開發(fā)調(diào)試神器Eruda的介紹與使用技巧

    移動端網(wǎng)頁開發(fā)調(diào)試神器Eruda的介紹與使用技巧

    在日常的移動端開發(fā)時,一般都是試用chrome瀏覽器的移動端模式進(jìn)行開發(fā)和調(diào)試,只有在chrome調(diào)試完成,而最近發(fā)現(xiàn)了一個新的調(diào)試方法,所以這篇文章主要給大家介紹了關(guān)于移動端網(wǎng)頁開發(fā)調(diào)試神器Eruda的基本資料,以及其使用的一些技巧,需要的朋友可以參考下。
    2017-10-10
  • 微信JS-SDK選取手機(jī)照片上傳功能

    微信JS-SDK選取手機(jī)照片上傳功能

    這篇文章主要為大家詳細(xì)介紹了微信JS-SDK選取手機(jī)照片上傳功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • 微信小程序身份證驗證方法實現(xiàn)詳解

    微信小程序身份證驗證方法實現(xiàn)詳解

    這篇文章主要介紹了微信小程序身份證驗證方法實現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-06-06
  • JS跨域解決方案之使用CORS實現(xiàn)跨域

    JS跨域解決方案之使用CORS實現(xiàn)跨域

    正常使用AJAX會需要正常考慮跨域問題,所以偉大的程序員們又折騰出了一系列跨域問題的解決方案,如JSONP、flash、ifame、xhr2等等。本文給大家介紹JS跨域解決方案之使用CORS實現(xiàn)跨域,感興趣的朋友參考下吧
    2016-04-04
  • 基于JS實現(xiàn)點(diǎn)擊圖片在彈出層顯示大圖效果

    基于JS實現(xiàn)點(diǎn)擊圖片在彈出層顯示大圖效果

    Javascript是個好東西。Jquery是基于這個好東西的一個強(qiáng)大的庫。本文將利用JavaScript實現(xiàn)點(diǎn)擊圖片在彈出層顯示大圖功能,感興趣的可以了解一下
    2022-08-08
  • 頁面使用密碼保護(hù)代碼

    頁面使用密碼保護(hù)代碼

    這是一個由JS實現(xiàn)的網(wǎng)頁密碼保護(hù)代碼,在進(jìn)入網(wǎng)頁前需要在彈出框中輸入密碼才可以,不過現(xiàn)在不怎么用了,一般情況下,目前都在后臺處理這種功能,用戶輸入用戶名和密碼后交給服務(wù)器處理,然后再返回信息,若登錄無誤就可看到某些內(nèi)容
    2013-04-04

最新評論

望都县| 黄大仙区| 通道| 大名县| 清水县| 遵义县| 灵寿县| 北京市| 大余县| 攀枝花市| 浏阳市| 湖州市| 萝北县| 邻水| 栖霞市| 无极县| 和平区| 庐江县| 嘉善县| 交城县| 怀安县| 左云县| 石屏县| 河东区| 龙口市| 务川| 宁城县| 澳门| 合川市| 延安市| 屯门区| 常山县| 富阳市| 宁河县| 西畴县| 宁乡县| 长顺县| 城市| 怀柔区| 孝昌县| 夹江县|