分解 Async/Await

2025-06-07

分解 Async/Await

Async/Await是 JavaScript 中令人惊叹的特性之一。它提供了一种以同步风格编写异步代码的卓越方法。是的,你没听错,这种模式允许开发人员编写人类可读的代码,而不仅仅是机器可读的代码。代码不仅供机器执行,也供人类解释和开发。

在深入研究语法糖之前,让我们先了解一下异步编程中的一些前辈,以了解为什么这种模式可以成为异步世界中的灵丹妙药。

回调

在 Promise 出现之前,回调是异步编程的解决方案。考虑到代码流程和复杂性,回调是当时 JavaScript 的痛点之一。是的,它给开发人员带来了很多麻烦。Inversion of control避免这种编程模式是主要考虑因素之一。

例如,考虑以下代码chunk

somethirdPartyLibrary.checkout(function doPayment() {
 initiatePayment();
})

假设你运营一个在线训练营,并使用第三方服务来处理结账流程。一旦图书馆决定向客户收费,它就会调用回调函数 doPayment 来记录付款。如果图书馆只调用一次回调,一切正常。但如果由于图书馆自身原因,多次调用回调,或者根本不调用,情况会怎样?这会导致一些严重的问题,并可能损害客户的信任。

我的天啊

这就是我们上面讨论的控制反转。我们将收费的控制权交给了图书馆。这是一种应该避免的奇怪模式,但它仍在使用中。

突然冒出一个功能请求:我们应该通知客户他们的订阅状态。我们将使用回调来实现这个功能。

somethirdPartyLibrary.checkout(function doPayment() {
 initiatePayment(function notifyAboutSuccess() {
     showSuccess();
   }, function notifyAboutFailure() {
     showFailure();
   }
 );
})

这会导致回调函数嵌套多次,有点让人困惑😓,对吧?现在,如果我们想要执行一个应该在成功通知后成功执行的操作,我们会将其嵌套为对notifyAboutFailure()的回调,这样很快就能进入成功通知了callback hell。我们的代码流程应该是这样的。

使困惑

救主的应许

Promise 为更多功能铺平了道路human-readable code。使用 Promise,我们的场景可以实现如下:

somethirdPartyLibrary.checkout()
.then(initiatePayment)
.then(showSuccess)
.catch(showFailure)

这里的流程很简洁,而且客户收费的控制权也在我们手中。有人可能会有疑问,如果 somethirdPartyLibrary.checkout 被解析多次,会不会then执行多次?不,并非如此,一个 Promise 只能被解析或拒绝一次。Promise 到目前为止都很好,这里唯一需要担心的是,如果某个任务依赖于一个 Promise 的解析,那么我们通常会把它们全部包装在then事件处理程序中,对吗?有什么神奇的解决方案asynchronous code可以让我们以某种方式编写synchronous

灵丹妙药来了🎯

使用 Async/Await 我们的实现可以重写,

(async function() {
  try {
    await somethirdPartyLibrary.checkout()
    await initiatePayment();
    showSuccess();
  } catch(err) {
    showFailure(err);
  }
})();

交易破坏者
这真是一个魔术吧?

打破它们

这种流程是用GeneratorsJavaScript 实现的。没错,Async/Await 是在底层借助生成器和 Promise实现的。

function resumeHandleCheckout() {
    iterator.next();
}

function* handleCheckout() {
    yield someThirdPartyLibrary.checkout();
    yield initiatePayment();
    showSuccess();
}

let iterator = handleCheckout();

let promiseFromLibrary = iterator.next();


promiseFromLibrary
.then(resumeHandleCheckout)
.then(resumeHandleCheckout)
.catch(showFailure);

你能理解Async/Await的底层机制吗?它处理了所有的复杂性,并为我们提供了语法糖

这确实是一个突破性的技术,因为它允许开发人员以同步风格编写异步代码,并且现在更加易于理解。欢迎与您的同事分享这篇文章。

文章来源:https://dev.to/theaswathprabhu/writing-down-async-await-ake
PREV
Common Node.js mistakes in Lambda Still using callbacks Not using promisify Too sequential async/await inside forEach() Not using AWSSDK’s .promise() Wrap-up
NEXT
使用 VS Code 做笔记