JavaScript 中的回调、Promises 和 Async/Await

2025-06-07

JavaScript 中的回调、Promises 和 Async/Await

JavaScript 是单线程的,这意味着同一时刻只能发生一件事。同步代码按照编写的顺序从上到下执行。同步代码也是“阻塞”的——每一行代码都会等待上一行代码执行完毕后才能运行。

相比之下,异步代码是“非阻塞”代码,它允许长时间运行的请求不阻塞主 JavaScript 线程。请求完成后,可以执行其他代码。这通常通过以下三种方式之一实现:

  1. 回调
  2. 承诺
  3. 异步/等待

让我们看几个例子,看看如何使用这三种方法编写异步代码。


回调

回调函数是作为参数传递给异步函数的函数。回调函数会在异步部分工作完成后执行。

让我们使用该方法模拟等待 API 请求返回响应setTimeout。回调方法可能如下所示:

function myAsyncMethod(callback) {
  console.log('myAsyncMethod was executed')
  setTimeout(callback, 1000)
}

function myCallbackMethod() {
  console.log('myCallbackMethod was executed')
}

myAsyncMethod(myCallbackMethod)
Enter fullscreen mode Exit fullscreen mode

这段代码首先会在控制台中打印“myAsyncMethod was performed”。然后等待一秒钟,再在控制台中打印“myCallbackMethod was performed”。


承诺

Promises 是另一种编写异步代码的方式,它可以帮助您避免深度嵌套的回调函数(也称为“回调地狱”)。Promise 可以处于以下三种状态之一:待处理 (pending)、已解决 (resolved) 或已拒绝 (rejected)。Promise 解决后,您可以使用promise.then()方法来处理响应。如果 Promise 被拒绝,您可以使用 方法来处理错误promise.catch()

我们可以使用如下承诺重写前面的示例:

function myAsyncMethod() {
  console.log('myAsyncMethod was executed')

  return new Promise((resolve, reject) => {
    setTimeout(resolve, 1000) 
  }) 
}

function myPromiseThenMethod() {
  console.log('myPromiseThenMethod was executed')
}

myAsyncMethod().then(myPromiseThenMethod)
Enter fullscreen mode Exit fullscreen mode

和以前一样,此代码将首先在控制台上打印文本“myAsyncMethod 已执行”。然后,它将等待一秒钟,然后再在控制台上打印文本“myPromiseThenMethod 已执行”。


异步/等待

Async/await 是 ES2017 中引入的新语法。它允许你以看似同步的方式编写异步代码,即使它实际上并非同步的。这使得代码更容易理解。

让我们再次重写示例,这次使用 async/await:

function myAsyncMethod() {
  console.log('myAsyncMethod was executed')

  return new Promise((resolve, reject) => {
    setTimeout(resolve, 1000) 
  })
}

function myAwaitMethod() {
  console.log('myAwaitMethod was executed')
}

async function init() {
  await myAsyncMethod()
  myAwaitMethod()
}

init()
Enter fullscreen mode Exit fullscreen mode

再次,此代码将首先在控制台上记录文本“myAsyncMethod 已执行”。然后,它将等待一秒钟,然后在控制台上记录文本“myAwaitMethod 已执行”。

注意我们是如何init使用async关键字来定义函数的。然后,我们await在调用函数之前使用了关键字来告诉代码,函数运行完成之前myAsyncMethod,我们不想运行下一行代码调用。myAwaitMethod myAsyncMethod

现在我们有了看似同步但实际异步运行的代码!Async/await 为我们提供了两全其美的优势:非阻塞代码,同时仍然易于阅读和理解。

文章来源:https://dev.to/thawkin3/callbacks-promises-and-async-await-in-javascript-44ia
PREV
开发训练营如何让学员失望
NEXT
在你的 React 中构建此分页