介绍
在 JavaScript 中,异步编程是非常重要的一部分。在 ES6 之前,我们使用回调函数、Promise 等方式来处理异步编程。而在 ES6 中,JavaScript 引入了 async/await 关键字,使得异步编程更加易用和可读。
async/await 是基于 Promise 的封装,只是语法更加友好,让我们可以更加方便地进行异步编程。从 ES2017(即 ES8)开始,async/await 又进行了优化和增强,使得其更加强大。
async 和 await 的用法
async
async 关键字用于定义一个异步函数,异步函数返回一个 Promise 对象。例如:
async function getData() { return 'Hello World!'; }
await
await 关键字用于暂停异步函数的执行,等待一个 Promise 对象它的状态变为 resolved,然后再继续执行异步函数。例如:
async function getData() { const data = await fetch('/api/data'); console.log(data); }
上面代码中,fetch 函数返回一个 Promise 对象,我们通过 await 暂停了 getData() 函数的执行,等待 Promise 对象返回数据后,才会继续执行。
需要注意的是,await 只能在异步函数中使用,其返回值为 Promise 对象 resolve 后的值。
async/await 的优点
1. 代码可读性更高
相比于回调函数和 Promise,async/await 代码的可读性更高。语法结构更加清晰,代码更加易读,连续异步操作如同同步一样,更符合想法和直观。
2. 异常和错误处理更加方便
使用 async/await 可以更加方便地进行异常和错误的处理。如果 await 返回的 Promise 对象 reject,那么将会抛出一个错误,我们可以使用 try/catch 来进行捕获。
async function getData() { try { const data = await fetch('/api/data'); console.log(data); } catch (error) { console.error(error); } }
3. 支持顺序执行
使用 async/await 可以实现顺序执行异步函数,代码结构更加清晰。下面是一个示例:
async function getData() { const data1 = await fetch('/api/data1'); const data2 = await fetch('/api/data2'); console.log(data1, data2); }
上面代码中,我们使用 await 实现了顺序执行 fetch('/api/data1') 和 fetch('/api/data2')。
async/await 的缺点
1. 可读性过度
在代码中, 添加了太多的async
和await
会使代码阅读更复杂且难懂, 这些代码看起来很难看, 因为异步操作的执行过程被过度强调。
2. 无法取消 Promise
在 await 等待一个请求的响应期间, 我们将无法取消这个 Promise 的请求。
3. 难以提前知道执行过程
我们可能需要阻塞程序的执行, 直到它处理完所有的异步请求。但是, 在使用 async/await 的情况下, 很难知道已经执行了哪些异步任务,并且单调等待完成状态可能会导致一些性能问题。
ES7 和 ES8 中的增强
1. 并行请求
在 ES7 中,可以使用 Promise.all() 方法,使多个异步请求可以并行处理。例如:
async function getData() { const [data1, data2] = await Promise.all([fetch('/api/data1'), fetch('/api/data2')]); console.log(data1, data2); }
上面代码中,我们使用 Promise.all() 方法,将 fetch('/api/data1') 和 fetch('/api/data2') 并行发起,可以加快响应速度。
2. Promise finally
在 ES8 中,Promise 对象增加了一个 finally 方法,该方法无论 Promise 对象状态如何,都会执行传入的回调函数。例如:
// javascriptcn.com 代码示例 async function getData() { try { const data = await fetch('/api/data'); console.log(data); } catch (error) { console.error(error); } finally { console.log('请求已完成'); } }
总结
通过本文的介绍,我们了解了 ES6、ES7 和 ES8 中的 async/await 关键字,以及其在异步编程中的优势和可读性,还介绍了其缺点和 ES7、ES8 中对其的优化和增强。
在实际的项目开发中,我们应根据具体情况选择使用回调函数、Promise 或 async/await 进行异步编程,以保证代码简洁、可读性高、易于维护。
参考资料
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65435a207d4982a6ebd0e6a1