纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

为什么await胜过Promise JS异步堆栈追踪之为什么await胜过Promise

浅笑·   2021-04-28 我要评论
想了解JS异步堆栈追踪之为什么await胜过Promise的相关内容吗,浅笑·在本文为您仔细讲解为什么await胜过Promise的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:js,await,jsPromise,异步,堆栈,下面大家一起来学习吧。

概述

async/await和Promise的根本区别在于await fn()暂停当前函数的执行,而promise.then(fn)在将fn调用添加到回调链后,继续执行当前函数。

const fn = () => console.log('hello')
const a = async () => {
  await fn() // 暂停 fn 的执行
}
// 调用 a 时,才恢复 fn 的执行
a() // "hello"

const promise = Promise.resolve()
// 将 fn 添加到回调链后,继续执行 fn
promise.then(fn) // "hello"

在堆栈追踪的上下文中,这种差异非常显著。

当一个Promise链(无论是否脱糖化)在任何时候抛出一个未经处理的异常时,JavaScript引擎都会显示一条错误信息和(希望)记录一个有用的堆栈追踪。

作为一名开发人员,无论您使用的是普通的Promise还是async await,您都会期望这样。

Promise

想象一个场景,当对异步函数b的调用解析时,调用函数c:

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

当调用a时,将同步发生以下情况:

  • b被调用并返回一个Promise,该Promise将在将来某个时刻解决。
  • .then回调(实际上是调用c())被添加到回调链中( V8 术语中,[…]被添加为解析处理程序)。

之后,我们完成了在函数a的主体中执行代码。a永远不会被挂起,当对b的异步调用解析时,上下文已经消失了。

想象一下如果b(或c)异步抛出异常会发生什么?理想情况下,堆栈追踪应该包括a,因为b(或c)是从那里调用的,对吧?既然我们不在参考a了 ,那怎样能做到呢?

为了让它工作,JavaScript 引擎需要在上面的步骤之外做一些事情:它在有机会的时候捕获并存储堆栈追踪。

在V8中,堆栈追踪附加到b返回的Promise。当Promise实现时,堆栈追踪将被传递,以便c可以根据需要使用它。

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

捕获堆栈追踪需要时间(即降低性能);存储这些堆栈追踪需要内存。

async/await

下面是同样的程序,使用async/await而不是Promise编写:

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

使用await,即使在await调用中不收集堆栈追踪,我们也可以恢复调用链。

这是可能的,因为a被挂起,正在等待b解决。如果b抛出异常,则可以按需以这种方式重建堆栈追踪。

如果c抛出异常,堆栈追踪可以像同步函数那样构造,因为发生这种情况时,我们仍在a上下文中。

通过遵循以下建议,使 JavaScript 引擎能够以更高效的方式处理堆栈追踪:

  • 偏好async/await胜过Promise。
  • 使用 @babel/preset env避免不必要的async/await传输。

相关文章

猜您喜欢

  • 详解Linux指令与文件的搜寻

    我们在管理Linux效劳器时通常会停止搜索文件及目录操作,下面我们就开端理解一下linux目录构造的相关学问..
  • java学生信息管理系统 java控制台实现学生信息管理系统(集合版)

    想了解java控制台实现学生信息管理系统(集合版)的相关内容吗,没事多喝水w在本文为您仔细讲解java学生信息管理系统的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:java学生信息管理系统,java学生管理系统,java信息管理系统,下面大家一起来学习吧。..

网友评论

Copyright 2020 www.iunios.com 【OS下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式