在异步编程中,ES5 中通过回调函数来描述异步操作,很容易导致回调地狱,即嵌套过多的回调函数难以管理和调试。ES6 引入 Promise 对象和 async/await 关键字,则能更清晰地表达异步行为,ES8 中对 async/await 做了更加完善的处理。
1. 异步函数的概念
异步函数,即 async 函数,是一个返回 Promise 对象的函数。相比起 Promise 对象来说,async 函数封装了更多的异步操作,通过简化代码的写法,提供了更多的便捷。
2. async/await 的用法
(1)async 函数声明
使用 async 关键字声明异步函数。
async function foo() { await someAsyncOperation(); // ... }
异步函数可以是匿名函数,并且异步函数表达式和 asyncFunctionDeclaration 区别不大。
const foo = async () => { await someAsyncOperation(); // ... };
(2)await 关键字
await 表示等待异步函数的 Promise 对象 resolve(或 reject)之后,再执行后续操作。在 async 函数中,await 关键字必须只能在 await 函数中使用。如不在 async 函数的函数体中使用,则会导致语法错误。
async function bar() { const result = await someAsyncOperation(); // ... }
若在同步代码或其他非 async 函数中使用 await,则会报错,警告错误信息,以符合函数体内使用的规范。
(3)async/await 常见应用
async/await 组合常用的场景在于并发请求,在得到多个请求结果之前等待全部结果。多数情况下,如果不使用 async/await 实现并发请求,代码可能就会混乱,例如,使用回调函数的方式,代码如下所示。
-- -------------------- ---- ------- -------- ---------------- --------- - ------------------------ -- - ------ ---------------- ------------ -- - --------------- --- - ------------------- ----- -- - ------------------- ----- -- - ------------------ ------- --- ---
如果我们想得到相同的结果,可以使用 async/await 实现。
-- -------------------- ---- ------- ----- -------- ---------------- - ----- -------- - ----- ----------- ------ ---------------- - ----- -------- --------- - ----- ----- - ----- -------------------- ----- ----- - ----- -------------------- ------------------ ------- -
3. 注意事项
使用 await 关键字会阻止后续代码的执行,等待异步操作完成后再回来执行后续代码。
使用 async/await 简化了异步代码的书写 😃,但如果不小心引起代码阻塞,可能也会有意想不到的意外。例如,改变了异步操作的参数,但并没有修改相应的 await 关键字,此时就会发现因为 await 导致的卡住。
4. 总结
ES8 中推出的 async/await 关键字能够更加优雅地描述异步行为,让开发者更加专注于代码的逻辑部分。当然,async/await 不是万能药水,我们在使用的时候,还需要关注更多的注意事项,防止因为使用不得当造成代码的阻塞,耗时加长。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64650f5e968c7c53b05df149