达到完美境界并不是无以复加,而是无可去除。——<安托万·德·圣·埃克苏佩里>
作者:Ashish Lahoti
译者:cl9000
来源:https://codingnconcepts.com/javascript/async-await-in-javascript/
Async 函数和 Await 关键字是 ECMAScript 2017 发布的最新 JavaScript 插件,它引入了一种编写异步函数的新方法。在这篇文章中,我们将讨论为什么我们应该使用 async/wait,它的语法和实例的实际用法。
为什么 Async/Await?
在早期,您可以使用回调来处理异步操作。然而,回调函数的功能有限,并且经常会导致难以管理的代码。如果你要处理多个异步调用,它会导致大量嵌套的回调代码,这也被称为回调地狱。
后来 ES6 中引入了Promise,以克服回调函数的问题并提高代码的可读性。最后,在 ES2017 中引入了 Async/Await,它只不过是Promise 的语法改进版本。它的底层是 Promise改进了语法,
- 链式
Promise和在链式Promise之间传递值的更好方法 - 与
Promise相比,代码更加简洁易读 - 调试是很容易的
- 更好的错误处理
语法
async
当 async关键字应用于函数之前时,它会转换为异步函数并始终返回 Promise 对象。
1 | async function hello() { |
Output
Promise {: “Hello”}
Hello
在上面的代码片段中,我们看到当我们执行 async 函数 hello() 时,它将字符串值包装在 Promise对象中,并返回一个解析后的 Promise。我们也可以显式返回已解析的 Promise对象,第2行和第3行是相同的。
然后我们进一步在已解析的 promise 对象上使用它来获取 Hellos字符串(第7行)
await
1 | // works only inside async functions |
await 关键字只在 async 函数内部有效,它使函数的执行等待,直到返回的 promise稳定下来( resolve 或 reject )。
1 | async function hello() { |
请注意,在上面的代码片段中,当我们执行异步函数 hello() 时,函数的执行在第6行等待5秒,然后返回已解析的 promise对象。CPU资源在此等待期间没有被利用,可以用于其他工作。
还要注意的是,如果你在非异步函数中使用 await关键字,它会像下面这样返回 SyntaxError:
1 | function hello() { |
用法
我们来看一个使用 fetch API从多个 HTTP 端点获取数据的实际例子。
1. 创建三个promise对象
我们已经创建了一个公共函数 getData,并使用它来创建三个参数化的 Promise 对象 getUser、getPosts 和 getComments,以从它们各自的 HTTP 端点获取数据。
1 | //create a common getData function |
2. 链式 Promise
我们的目标是获取第一个用户在第一篇文章上的所有评论。
我们首先从 getUsers promise中获取所有用户,并通过传递 firstUser 将其与getPost promise 链接起来。通过传递 firstPost,进一步将它与 getComments promise 链接起来。
1 | //promise chaining of multiple asynchronous calls |
Output
▼ (5) [{…}, {…}, {…}, {…}, {…}]
➤ 0: {postId: 1, id: 1, name: “id labore ex et quam laborum”, email: "Eliseo@gardner.biz", body: “laudantium enim quasi est quidem magnam voluptate …utem quasi↵reiciendis et nam sapiente accusantium”}
➤ 1: {postId: 1, id: 2, name: “quo vero reiciendis velit similique earum”, email: "Jayne_Kuhic@sydney.com", body: “est natus enim nihil est dolore omnis voluptatem n…iatur↵nihil sint nostrum voluptatem reiciendis et”}
➤ 2: {postId: 1, id: 3, name: “odio adipisci rerum aut animi”, email: "Nikita@garfield.biz", body: “quia molestiae reprehenderit quasi aspernatur↵aut …mus et vero voluptates excepturi deleniti ratione”}
➤ 3: {postId: 1, id: 4, name: “alias odio sit”, email: "Lew@alysha.tv", body: “non et atque↵occaecati deserunt quas accusantium u…r itaque dolor↵et qui rerum deleniti ut occaecati”}
➤ 4: {postId: 1, id: 5, name: “vero eaque aliquid doloribus et culpa”, email: "Hayden@althea.biz", body: “harum non quasi et ratione↵tempore iure ex volupta…ugit inventore cupiditate↵voluptates magni quo et”}
length: 5
➤ proto: Array(0)
3. async/await
我们使用 async/await 实现获取评论同样的目标
1 | //async and await makes code cleaner and readable |
Output
▼ (5) [{…}, {…}, {…}, {…}, {…}]
➤ 0: {postId: 1, id: 1, name: “id labore ex et quam laborum”, email: "Eliseo@gardner.biz", body: “laudantium enim quasi est quidem magnam voluptate …utem quasi↵reiciendis et nam sapiente accusantium”}
➤ 1: {postId: 1, id: 2, name: “quo vero reiciendis velit similique earum”, email: "Jayne_Kuhic@sydney.com", body: “est natus enim nihil est dolore omnis voluptatem n…iatur↵nihil sint nostrum voluptatem reiciendis et”}
➤ 2: {postId: 1, id: 3, name: “odio adipisci rerum aut animi”, email: "Nikita@garfield.biz", body: “quia molestiae reprehenderit quasi aspernatur↵aut …mus et vero voluptates excepturi deleniti ratione”}
➤ 3: {postId: 1, id: 4, name: “alias odio sit”, email: "Lew@alysha.tv", body: “non et atque↵occaecati deserunt quas accusantium u…r itaque dolor↵et qui rerum deleniti ut occaecati”}
➤ 4: {postId: 1, id: 5, name: “vero eaque aliquid doloribus et culpa”, email: "Hayden@althea.biz", body: “harum non quasi et ratione↵tempore iure ex volupta…ugit inventore cupiditate↵voluptates magni quo et”}
length: 5
➤ proto: Array(0)
总结
我们看到 async/await 比 promise 更容易使用。
参考
- https://codingnconcepts.com/javascript/async-await-in-javascript/
- MDN - https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function
- MDN - https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/await
关注【公众号】,了解更多。
关注【公众号】,了解更多。
关注【公众号】,了解更多。

赞赏一下 坚持原创技术分享,您的支持将鼓励我继续创作!
支付宝打赏
微信打赏