达到完美境界并不是无以复加,而是无可去除。——<安托万·德·圣·埃克苏佩里>
作者: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
对象上使用它来获取 Hello
s字符串(第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
关注【公众号】,了解更多。
关注【公众号】,了解更多。
关注【公众号】,了解更多。
赞赏一下 坚持原创技术分享,您的支持将鼓励我继续创作!