在 ES8 中使用 for await...of 实现并发异步任务
随着前端技术的不断发展,以往的 JavaScript 在并发处理异步任务上显得力不从心。为了解决这一问题,ES8 中引入了新的关键字 for await...of,可用于处理并发的异步任务。
在介绍 for await...of 之前,我们先来讲解 Promise 和 async/await,这两个概念是实现并发异步任务的基础。Promise 是解决 JavaScript 异步回调问题的重要工具,而 async/await 则是 Promise 的高级应用,提供了更加简洁的异步处理方式。
在处理多个异步任务时,我们可以通过 Promise.all 方法并发处理多个异步任务,代码如下:
Promise.all([promise1, promise2, promise3]) .then(results => { console.log('All promises are resolved', results); }) .catch(error => { console.error('Something went wrong', error); });
Promise.all 方法是将多个 Promise 对象包装成一个新的 Promise,只有在所有 Promise 都成功返回后才会执行 then 方法。但是,当其中某个 Promise 失败时,Promise.all 方法就会执行 catch 方法,从而返回一个 rejected 状态的 Promise。
接下来,我们需要了解 async/await。async/await 是对 Promise 的更高层次封装,使用它我们可以将异步操作转换为同步的方式。async/await 基于 Promise,而不是取代了 Promise。async 函数返回的是一个 Promise 对象,可以使用 await 关键字等待异步操作完成。
考虑以下示例代码,我们使用 async/await 处理读取多个文件的操作:
-- -------------------- ---- ------- ----- -------- ----------- - ----- ----- - ------------- ------------ ------------- --- ------ ---- -- ------ - ----- ------- - ----- --------------- -------------------- -- -------- ------------- - - ----- -------- -------------- - ------ --- ----------------- ------- -- - ----------------- ------- ----- -- - -- ------- - -------------- - ---- - ------------------------- - --- --- -展开代码
上述代码通过 for 循环处理了每个文件,并使用 await 等待每个 Promise 的结果。但是,这样的处理方式还是有限制的。当文件读取操作之间并无依赖关系,我们可以使用 Promise.all 并发执行 Promise 对象,但是一旦存在依赖关系,就无法使用 Promise.all 并发执行了,为此,我们需要引入 for await...of。
for await...of 中的 await 支持返回 Promise 的任意对象,不仅限于 Promise 实例。也就是说可以使用 for await...of 处理异步迭代器的方式实现并发异步任务。
接下来,我们用一个实际的示例来说明这个机制,我们需要批量生成十个用户,并向每个用户发送一封电子邮件:
-- -------------------- ---- ------- ----- -------- ------------- - ------ --- ----------------- ------- -- - ------------- -- - ------------------ ------------ ---- -- -------- ---------- -- ------------------------ - ------- --- - ----- --------- --------------------- - ----- ----- - - ------ ------ ------ ------------------- ------ -------- ------ --------------------- ------ ------- ------ -------------------- ------ ------- ------ -------------------- ------ ------- ------ -------------------- ------ ------- ------ -------------------- ------ ------- ------ -------------------- ------ -------- ------ --------------------- ------ ------ ------ ------------------- ------ ------- ------ -------------------- -- --- ------ ---- -- ------ - ----- ------ ------ - ----- ----------------------- ----- --- ---------- ----- ----------------- - - ------ ---------- - ----- -------------- - ---------------------- --- ----- ------ ------ -- --------------- - -------------------- - -----展开代码
上述代码通过 yield 关键字将 sendEmail 方法转换为异步迭代器,使用 for await...of 处理异步迭代器来并发执行十个异步操作,从而实现了并发处理异步操作的效果。
总之,ES8 中的 for await...of 关键字是处理并发异步任务的最佳工具,是由 async/await、Promise 和 Generator 等技术实现的高级应用,非常适用于请求大量数据、批量发送信息、短信验证等场景,同时也非常容易上手。在开发过程中,我们应该学会使用它来提高代码效率,加速开发进程。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67cf0a68e46428fe9e9e62d1