Node.js stream
的命令是否最多保存并包含'data'
事件?我相信它们是正确的,this question似乎也暗示至少pipe
方法是顺序的。
我希望保留块顺序,以便我可以在流结束之前调用对每个块进行操作的函数,即,在读取流的一部分时,我希望缓冲的数据块可以由流处理。 'data'
事件中发挥作用。
但是,当我运行以下代码时,我使用Math.random
和setTimeout
专门测试了事件是否按顺序发生:
fs.createReadStream(filePath, { encoding: 'ascii' })
.pipe(streamToEntry)
.on('data', (chunk) => {
setTimeout(() => {
console.log(chunk);
}, Math.random() * 1000)
});
数据块可以无序记录。
这是由于setTimeout()
还是因为'data'
事件不一定按顺序调用吗?也就是说,应仅在pipe
方法中进行有序处理,还是可以在序列末尾顺序处理数据?
答案 0 :(得分:1)
您的data
事件被保证按顺序发出。有关节点的源代码的一些其他详细信息和摘要,请参见this answer。这表明确实可以按顺序获得data
事件。
当您在data
回调中添加异步代码时,就会出现问题(setTimeout
是异步代码的示例)。在这种情况下,不能保证您的data
回调函数会按照被调用的顺序完成处理。
您需要做的是确保在您的data
回调返回时,您已经完全处理了数据。换句话说,您的回调代码必须是同步代码。
fs.createReadStream(filePath, { encoding: 'ascii' })
.pipe(streamToEntry)
.on('data', (chunk) => {
// only synchronous code here
console.log(chunk);
});
要使问题代码正常工作,可以使用async
/ await
:
fs.createReadStream(filePath, { encoding: 'ascii' })
.pipe(streamToEntry)
.on('data', async (chunk) => {
// only synchronous code here
await setTimeout(() => console.log(chunk), Math.random() * 1000);
});