在 ECMAScript 2017 中,引入了异步函数的概念。它通过 async 和 await 关键字简化了异步流程的编写过程,使得回调地狱和 Promise 嵌套的问题得到了很好的解决。
在 ECMAScript 2020 中,await 关键字的功能得到了升级,加入了新的特性,本文将一一介绍。
问题
在讲新特性之前,我们先回顾一下在旧版的 await 中,可能存在的问题。
async function getOrder(orderId) { const order = await getOrderById(orderId); const items = await getOrderItems(orderId); const customer = await getCustomerById(order.customerId); return { ...order, items, customer }; }
在上面的代码中,我们通过 await 等待 getOrderById、getOrderItems 和 getCustomerById 函数的执行结果。这里需要注意的是,这三个函数是单独依次执行的,因此如果它们之间互不依赖,我们是可以进行并行优化的,以提高程序执行效率。
但是,在上面的代码中,由于我们必须等待前一个函数的执行结果,才能开始下一个函数的执行,因此无法实现并行优化。这时候,就需要使用 Promise.all:
async function getOrder(orderId) { const [order, items, customer] = await Promise.all([ getOrderById(orderId), getOrderItems(orderId), getCustomerById(order.customerId) ]); return { ...order, items, customer }; }
我们使用 Promise.all 将三个函数的执行结果同时等待,并将其放入一个数组中返回。这样,通过并行优化,我们可以极大地提高程序执行效率。
然而,在使用 Promise.all 的时候,如果有某个函数执行失败,整个 Promise 就会被 reject,需要手动处理异常。因此,Promise.all 并不能完全适用所有情况。
新特性
为了解决上文中提到的问题,ECMAScript 2020 中加入了新的特性:Promise.any 和 AggregateError。
Promise.any 可以将多个 Promise 同时执行,一旦有一个 Promise 成功,则返回该 Promise 的执行结果。如果所有 Promise 都失败,则返回 AggregateError 类型的异常。
async function getOrder(orderId) { const [order, items, customer] = await Promise.any([ getOrderById(orderId), getOrderItems(orderId), getCustomerById(order.customerId) ]); return { ...order, items, customer }; }
在上述代码中,我们仍然使用数组将多个异步操作进行了封装。但是在这个场景下,我们一旦得到其中任意一个异步操作的结果,就可以直接返回数据,并且避免了不必要的等待时间。这正好符合了 await 的设计目标。
除此之外,如果有多个异步操作都返回异常,这时候 Promise.any 将会返回 AggregateError。它是一个新的异常类型,具有一个 errors 属性,该属性包含了所有异常对象的数组。我们可以使用 try...catch... 捕获 AggregateError,并针对多个异常做出相应的处理。
-- -------------------- ---- ------- ----- -------- ----------- - --- - ----- ------------- ------------------ ------------ ----- ------------------ ------------ ----- ------------------ ------------ ---- --- - ----- ----- - -- ---- ---------- --------------- - ----- ------ - ----------- ---------------------- -- ------- ----- -- ------ ----- -- ------ ----- -- - - -
结论
Promise.any 的出现,使得我们可以更加自由地组合异步操作,并提高程序执行效率。它可以避免因某个操作很慢而导致程序整体时间过长的问题。同时,AggregateError 可以更好地处理异常情况,以提高程序的健壮性。
以上内容是 ECMAScript 2020 中 await 的新特性,相信能够帮助广大前端开发者更好地编写优秀的异步代码。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67065eecd91dce0dc85c7086