Node.js`Stream`和块顺序

时间:2018-10-29 07:55:11

标签: node.js stream

Node.js stream的命令是否最多保存并包含'data'事件?我相信它们是正确的,this question似乎也暗示至少pipe方法是顺序的。

我希望保留块顺序,以便我可以在流结束之前调用对每个块进行操作的函数,即,在读取流的一部分时,我希望缓冲的数据块可以由流处理。 'data'事件中发挥作用。

但是,当我运行以下代码时,我使用Math.randomsetTimeout专门测试了事件是否按顺序发生:

fs.createReadStream(filePath, { encoding: 'ascii' })
  .pipe(streamToEntry)
  .on('data', (chunk) => {
    setTimeout(() => { 
      console.log(chunk); 
    }, Math.random() * 1000)
  });

数据块可以无序记录。

这是由于setTimeout()还是因为'data'事件不一定按顺序调用吗?也就是说,应仅在pipe方法中进行有序处理,还是可以在序列末尾顺序处理数据?

1 个答案:

答案 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); 
  });