跳到主要内容

深入理解 await 与 async

· 阅读需 4 分钟
素明诚
Full stack development

1. 基本概念

什么是 async 函数?

async 函数是一个返回 Promise 对象的函数。在函数内部,你可以使用 await 关键字来等待一个 Promise

什么是 await 关键字?

await 关键字只能在 async 函数内部使用,它会暂停当前函数的执行直到 Promise 完成,并返回结果。

async 函数返回什么类型的值?

async 函数总是返回一个 Promise


2. 错误处理

如何在使用 await 时处理错误?

使用 try/catch 结构。

try/catch 在 async/await 中的作用是什么?

它用于捕获 await 表达式中的错误或在 async 函数内部抛出的错误。

如何处理多个 await 调用中的并发错误?

  1. 如果你使用 Promise.all() 来同时等待多个 Promise,它会在其中一个 Promise 失败时立即失败。
  2. 你可以在这种情况下使用 try/catch 来捕获错误。

3. 并发性

如何并发地执行多个 await 操作?

你可以使用 Promise.all() 或者 Promise.allSettled() 来并发执行多个 Promise

Promise.all()和 Promise.race()在与 async/await 结合时有什么作用?

  1. Promise.all() 允许你并发等待多个 Promise,它返回一个 Promise,该 Promise 在所有的 Promise 完成后完成。
  2. Promise.race() 返回一个 Promise,该 Promise 在第一个 Promise 完成后完成。

4. 与 Promise 的关系

async/await 和 Promises 之间有什么关系?

async/await 是基于 Promise 的,并提供了一种更简洁、更直观的方式来处理 Promise

在 async 函数中返回一个值等价于哪种 Promise 操作?

  1. 返回一个值等价于 Promise.resolve()
  2. 抛出错误等价于 Promise.reject()

5. 执行顺序

描述一个包含多个 await 语句的 async 函数的执行顺序。

函数会从顶部开始执行,当遇到第一个 await 语句时暂停,直到该 Promise 完成。然后,函数会继续执行,直到遇到下一个 await 或函数结束。

何时使用 await 和何时避免使用?

  1. 当你需要按顺序执行异步操作时,使用 await
  2. 当你可以并发执行多个操作时,使用 Promise.all() 或其他类似的方法。

6. 错误和陷阱

描述在使用 async/await 时可能遇到的常见错误或陷阱。

  1. 忘记 await
  2. 在非 async 函数内部使用 await
  3. 在循环中不正确地使用 await 导致不必要的顺序执行。
  4. 未处理的异步错误。

如何避免“忘记 await”的问题?

使用 TypeScript 或 ESLint,它们可以检测这种常见错误。


7. 实际应用

这通常涉及将给定代码片段转换为使用 async/awaitPromises。这要根据具体的代码片段来决定。


8. 浏览器和 Node.js 支持

哪些版本的 Node.js 和浏览器开始支持 async/await?

Node.js 从 7.6.0 版本开始支持 async/await。大多数现代浏览器都支持它,但旧版本的浏览器可能不支持。

在不支持 async/await 的环境中,如何使用它?

你可以使用 Babel 或 TypeScript 这样的转译器将 async/await 转换为 ES5 或 ES6 JavaScript。


9. 性能和最佳实践

async/await 是否比纯 Promises 更慢?

在大多数情况下,性能差异是可以忽略的。但 async/await 可能会带来一些额外的运行时开销。

何时应该使用 async/await,何时应该使用 Promises?

  1. 当你需要更简洁和可读的代码时,使用 async/await
  2. 对于复杂的异步逻辑或需要更细粒度控制的场景,使用 Promises

10. 其他特性和提议

对于 async iterators 和 for-await-of 的了解。

  1. async iterators 是一种可以异步生成值的迭代器。
  2. for-await-of 是一种循环结构,允许你等待 async iterator 的每个值。

了解其他与 async/await 相关的 ES 提议,如顶级 await。

顶级 await 是一个提议,允许你在模块的顶级使用 await,而不是仅在 async 函数中。