for of 循环如何处理在 javascript 中不可迭代的流
How do for of loops handle streams which aren't iterable in javascript
在节点中,我们可以使用 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 语句并忽略该行?
As I understood, the for(x of y) syntax works with iterables. However streams are not iterable, so how does this work?
for-of
确实需要一个可迭代对象,但该代码使用的是 for-await-of
,它需要一个 async
可迭代对象,而不是可迭代对象.这是两个不同(尽管密切相关)的事情。 :-) 可读流 are async
iterable,因此您可以对它们使用 for-await-of
。请注意,async
可迭代的东西可能不可迭代(我怀疑它们通常不是,因为它们无法同步提供结果)。
I want to ignore the first line emitted on rl
.
有几种方法可以做到这一点:
- 使用标志
- 直接获取
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-of
和 for-await-of
一起使用。
在节点中,我们可以使用 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 语句并忽略该行?
As I understood, the for(x of y) syntax works with iterables. However streams are not iterable, so how does this work?
for-of
确实需要一个可迭代对象,但该代码使用的是 for-await-of
,它需要一个 async
可迭代对象,而不是可迭代对象.这是两个不同(尽管密切相关)的事情。 :-) 可读流 are async
iterable,因此您可以对它们使用 for-await-of
。请注意,async
可迭代的东西可能不可迭代(我怀疑它们通常不是,因为它们无法同步提供结果)。
I want to ignore the first line emitted on
rl
.
有几种方法可以做到这一点:
- 使用标志
- 直接获取
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-of
和 for-await-of
一起使用。