【问题标题】:How do for of loops handle streams which aren't iterable in javascriptfor of 循环如何处理在 javascript 中不可迭代的流
【发布时间】:2021-06-29 05:40:44
【问题描述】:

在节点中,我们可以使用createReadStream 为文件创建一个读取流,然后基于该流,我们使用readline.createInterface 获取一个新的流,该流逐行发出数据。

const fileStream = fs.createReadStream(inputFilePath);
const rl = readline.createInterface({
  input: fileStream,
  crlfDelay: Infinity
});

for await (const line of rl) {
  // do something
}

我有两个相关的问题:

  • 据我了解,for(x of y) 语法适用于可迭代对象。但是流是不可迭代的,那么它是如何工作的呢?
  • 我想忽略rl 发出的第一行。 rl 上没有 next() 函数,因为它不是可迭代的。因此,如果我想跳过第一行,可以通过跟踪我们之前是否已经收到一行来执行此操作,然后在 for of 循环内使用 if 语句并忽略该行?

【问题讨论】:

    标签: javascript node.js stream iterable


    【解决方案1】:

    据我了解,for(x of y) 语法适用于可迭代对象。但是流是不可迭代的,那么它是如何工作的呢?

    for-of 确实需要一个可迭代对象,但该代码使用的是for-await-of,它需要一个async 可迭代对象,而不是可迭代对象。这是两个不同(尽管密切相关)的东西。 :-) 可读流are async iterable,因此您可以在它们上使用for-await-of。请注意,async 可迭代的东西可能不可迭代(我怀疑它们通常不是可迭代的,因为它们无法同步提供结果)。

    我想忽略rl 发出的第一行。

    有几种方法可以做到这一点:

    1. 使用标志
    2. 直接获取async迭代器并调用next

    使用标志:

    let first = true;
    for await (const line of rl) {
        if (first) {
            first = false;
            continue;
        }
        // do something
    }
    

    直接使用async 迭代器:

    let it = rl[Symbol.asyncIterator](); // Get the async iterator
    await it.next();                     // Skip the first result -- note `await`
    for await (const line of it) {       // Works in most cases because the async
       /* Note `it` not `rl` ^^ */       // *iterator* is also an async *iterable*
                                         // (and that's true of the one you get
                                         // from `readline`)
        // do something
    }
    

    迭代器/async 迭代器通常通过执行return this 来实现Symbol.iterator/Symbol.asyncIterator,这使得迭代器可迭代,因此它们可以与for-offor-await-of

    【讨论】:

    • FWIW,我在最近的一本书 JavaScript: The New Toys 的第 6 章和第 9 章中详细介绍了 iterables 和 async iterables。如果您有兴趣,请在我的个人资料中链接。
    猜你喜欢
    • 2022-01-07
    • 1970-01-01
    • 2015-06-11
    • 1970-01-01
    • 2019-12-08
    • 2017-08-06
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多