在 JavaScript 的异步编程中,Promise 和 async/await 已经极大地帮助了我们。然而,当需要处理多个异步操作的流时,这些工具仍然不够方便。ES8 的 for-await-of 循环是一个很好的解决方案,它使我们可以迭代异步流数据,从而更轻松地将流数据转换为顺序数据。
for-await-of 简介
for-await-of 循环使用与 for-of 循环相同的语法,但是不仅仅可以遍历迭代器和数组,还可以遍历异步数据流。for-await-of 本质上是在 Promise 的基础上构建的。它会自动调用 Promise 的 resolve,以使 Promise 变为等待 Promise 完成的状态。
我们来看一个示例:
-- -------------------- ---- ------- ----- --------- -------- - ----- ------------------- ----- ------------------- ----- ------------------- - ------ -- -- - --- ----- ---- ----- -- --------- - ------------------- - -----展开代码
这个示例定义了一个生成器函数,使用了 async 和 yield。生成器函数中 yield 的是 Promise 对象。在 for-await-of 循环中,我们可以像遍历数组一样遍历 stream() 生成器,for 循环自动等待 Promise 执行完成。运行结果为:
1 2 3
我们可以将 for-await-of 循环理解为在 Promise 和 Iterator 上的语法糖。使用 for-await-of 循环遍历数据流非常方便。
迭代异步流的应用
for-await-of 循环可以应用于非常多的场景,包括处理多个异步请求、迭代数据库查询的结果、处理流媒体等。接下来,我们举几个例子来说明如何使用 for-await-of 循环。
使用 for-await-of 在列表中查找结果
假设我们有一个表示某些状态的数字列表。我们需要查找其中第一个大于或等于 100 的数字。为了实现这个需求,我们可以定义一个通过 API 获取数据的异步获取函数 fetch,并将其传递到一个 for-await-of 循环来迭代要查找的数字列表。
-- -------------------- ---- ------- ----- ---- - ---- --- ---- ----- ----- -------- --------- - ------ ------------------ - ---- - ----- -------- ------ - --- ----- ---- - -- ----- - ----- ------ - ----- --------- -- ------- -- ---- - -------------------- ------ - - - -------展开代码
我们定义好页面列表后,在 for-await-of 循环中设置异步获取数据的 fetch 函数,即可非常方便的实现对象查询并返回第一个符合条件的查询结果。
使用 for-await-of 迭代异步操作的数据流
下面,我们来介绍如何使用 for-await-of 迭代异步操作的数据流。假设我们需要同时调用三个 API,我们可以使用 Promise.race() 方法和一个 while 循环来实现这个需求。但是,for-await-of 循环可以使我们的代码更加清晰,避免了循环的复杂性。
我们首先定义一个异步函数 fetchData,来模拟 API 请求。我们将它传递给三个 for-await-of 循环,在其中分别调用 fetchData 方法,来测试它们是一起调用还是顺序调用。
-- -------------------- ---- ------- ----- -------- ---------------- - ---------------------- ------ ----------- ----- --- --------------- -- ------------------- ------- ---------------------- ---- ----------- ------ ------ - ------ -------- -- - ----- -------- - --------------------------------- -- -------------- --- ----- ---- ------ -- --------- - -------------------- ----- ------------ - -----展开代码
我们可以看到,它们是并行调用的。代码的运行结果如下:
-- -------------------- ---- ------- --------- ------ - --------- ------ - --------- ------ - --------- ---- - ------- ----- - --------- ---- - ------- ----- - --------- ---- - ------- ----- -展开代码
对于迭代异步数据流的指导
for-await-of 循环是一个很强大的解决异步数据流迭代问题的方法,但它也有其局限性。它不会自动停止,也不会处理错误。在使用 for-await-of 循环时需要注意以下几点:
- 对于过大的数据量,应该避免使用 for-await-of 循环,以免崩溃;
- 需要错误处理,建议加上 try-catch 语句捕获错误;
- 当使用 for-await-of 循环迭代数据流时,尝试使用有限的 buffer 和批量处理,以便减少内存使用和减少 CPU 时间。
总之,for-await-of 循环是一种方便、强大和易于使用的迭代器,可以很好地处理异步操作的数据流,并且可以简化代码。我们应该利用这种方法来处理大部分需要迭代异步操作的场景,提高代码可读性和可维护性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67b6b710306f20b3a62e6f67