JavaScript 中的异步循环 for...wait...of

134 阅读2分钟

前言

JavaScript 中的循环结构包括 for 、 forEach 、map 、 do...while 、 while 、 for...in 和 for...of 。所有这些构造都在同步迭代器(如数组、对象、字符串等)上循环。

但是,如果您想遍历异步可迭代对象(例如读取文件、构造器或任何实现异步可迭代协议的对象)怎么办?

为此,ECMAScript 2015 中存在一个特殊的循环结构。 for...await...of 。

 for...await...of 是什么?

for…await…of 语句创建了一个循环,遍历异步可迭代对象以及同步可迭代对象,例如我之前提到的数组、对象、字符串。下面是如何编写这样一个循环。

var asyncIterable = {
  [Symbol.asyncIterator]: asyncIterator
};

(async function() {
  for await (variable of asyncIterable) {
    //一些执行的代码逻辑
  }
})(); 

variable - 在每次迭代中,都会将不同属性的值分配给变量。变量可以用 const 、 let 或 var 声明。

 iterable - 其可迭代属性将被迭代的对象。

for...wait...of 循环首先通过 [Symbol.asyncIterator]() 创建数据源。每次调用 next() 时,循环都会隐式等待解决 Promise 。这个 Promise 由迭代器方法返回。注意这里,因为它使用了 await ,所以你必须像普通的 await 一样在 async 函数中使用它。

现在,举个例子,如果你想读取一个异步操作的文件,你可以这样做。

(async function() {
  for await (const line of readLines(filePath)) {
    console.log('line',line)
  }
})(); 

readLines()函数 是读取文件内容的函数,这里不再赘述。

让我们举一个使用 JavaScript Generator构造器的更现实的例子。

async function* asyncGenerator() {
    var array = ['Hello', 'World'];

    while (array.length) {
      yield await array.shift();
    }
}

(async function() {
  for await (const item of asyncGenerator()) {
    console.log(item);
    // 'Hello'
    // 'World'
  }
})(); 

在这里, asyncGenerator 是一个异步构造器,它异步返回数组项。在这里,构造器是异步的,因为它与同步构造器不同,它异步返回所有值。 for...wait...of 循环在移动到 next() 之前等待每个项目都解决。在这里, next() 也是异步的,它返回 Promise。因此,它可以循环使用 for await…of 循环。

全文完

谢谢!

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 24 天

点击查看活动详情