在 ES8 之前,JavaScript 的异步编程主要依赖于回调函数和 Promise。但是这些方法都有一定的局限性,比如 callback hell 和 Promise 很难处理多个异步请求并发的问题。ES9 中提供了一个新的循环结构,for-await-of 循环,来解决这些问题。
for-await-of 循环的基本用法
for-await-of 循环用于遍历异步迭代器(async iterators)中的成员对象,且每个成员对象会依次等待前一个成员对象完成后再进行下一个。异步迭代器需要实现 Symbol.asyncIterator 方法,返回一个异步迭代器对象。
以下是一个基本示例,演示了如何使用 for-await-of 循环遍历异步迭代器:
-- -------------------- ---- ------- ----- -------- ----------- - --- ---- - - -- - -- -- ---- - ----- --- --------------- -- - ------------- -- - ---------------------- ------- ---------- -- - - ------ --- ----- -- - - ------ ---------- - --- ----- ------ ---- -- ------------ - --------------------- ---------- - -----
在上述例子中,asyncIter 函数是一个异步迭代器,通过 yield 依次返回 1,2,3。for-await-of 循环通过 await 等待每个成员对象执行完成后输出相应的结果。
for-await-of 循环的应用场景
for-await-of 循环适用于以下几种场景:
- 并行执行多个异步任务,并进行适当的控制。
- 遍历具有异步特性的数据源。
- 实现异步的自定义迭代器。
以下是针对上述场景的具体操作:
并行执行多个异步任务,并进行适当的控制
对于多个异步任务并发的情况,我们可以使用 Promise.all 方法将多个 Promise 对象合并成一个 Promise 对象。但是使用 for-await-of 循环可以更加灵活的控制异步任务,并进行相应的异常处理。以下是一个例子:
-- -------------------- ---- ------- ----- -------- --------------- - ----- --- --------------- -- - ------------- -- - ---------------------- ---------- ---------- -- ------ --- - ----- -------- --------- - ----- ----- - ----------------- --------------- ----------------- --- ----- ------ ---- -- ------ - ----------------- ------------ - - ----------
在上述例子中,异步任务执行的时间不同,通过 for-await-of 循环等待每个异步任务执行完成后再进行下一个异步任务的执行。
遍历具有异步特性的数据源
通过异步迭代器实现异步的数据遍历,可以避免数据加载阻塞 UI 线程,提高用户体验。以下是一个例子:
-- -------------------- ---- ------- ----- --------- ----------- - ----- ------ - --------------------------------------------- ----- -------- - ----- -------------- ----- ---- - ----- ---------------- --- ------ ---- -- ----- - ----- ----- - - ------ ---------- - --- ----- ------ ---- -- ------------ - ------------------------ - -----
在上述例子中,利用 fetch 方法异步获取数据,并通过 yield 关键字,逐个返回数据,利用 for-await-of 循环,等待每个数据返回后再进行下一个数据的访问。
实现异步的自定义迭代器
自定义迭代器可以更加灵活的控制迭代过程,处理复杂的业务逻辑。下面是一个例子:
-- -------------------- ---- ------- ----- ------------ - ------------------ - ----------------- - -- ---------- - ------ - ------------------------ - ------ - ----- ----- -- -- - ----- --- --------------- -- ------------------- ------- -- ------------------ - ----------- - ------ - ------ -------------------- ----- ----- -- - ---- - ------ - ----- ---- -- - - -- - - ------ ---------- - ----- ------- - --- ---------------- --- ----- ------ ---- -- -------- - ------------------- ---------- - -----
上述例子中,我们自定义了一个异步计数器,通过 Symbol.asyncIterator 方法进行异步迭代。每个异步迭代器通过 next 方法返回一个 Promise 对象,等待 1 秒后返回当前值,直到当前值达到预设的 limit 值后,done 变为 true,迭代结束。
总结
for-await-of 循环提供了一种更加灵活的异步编程方式,通过异步迭代器实现了对具有异步特性的数据源的访问和自定义迭代器的实现。在实际开发中,可以运用到并行执行多个异步任务时,并控制异步任务的执行顺序等场景,提高开发效率和用户体验。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64744f29968c7c53b01b0803