Node.js ReadableStream和异步事件监听器

时间:2017-12-03 01:02:11

标签: node.js stream node.js-stream

有人可以解释以下行为吗?这肯定是由于异步I / O,但下面的代码基于许多简单的例子,其中一些来自SO,显然没有讨论这里的问题,其中流没有按预期读取。

解决方案是什么?我试图从第一原理中理解潜在的问题,所以请不要建议我使用已发布的npm stream->字符串包。感谢。

给定文件n.js

'use strict';

const streamToString = (s, cb) => {
  const chunks = []

  s.on('readable', () => {
    console.log('data')
    let chunk
    while( null !== (chunk = s.read())) {
      chunks.push(chunk)
    }
  })
  s.on('end', () => {
    console.log('end')
    cb(Buffer.concat(chunks).toString())
  })
}

let o
const f = (str) => {
  o = JSON.parse(str)
}

const fs = require('fs')
const rs = fs.createReadStream('t.json')
streamToString(rs, f)

console.log('o = ' + o)

在终端

$ uname -a
Linux bsh 4.10.0-40-generic #44~16.04.1-Ubuntu SMP Thu Nov 9 15:37:44 UTC        2017 x86_64 x86_64 x86_64 GNU/Linux
$ node --version
v6.12.0
$ node n.js
o = undefined
data
data
end

输出适用于任何非空输入文件,包含简单验证的JSON。

我也尝试过'读'事件,即

  s.on('read', (chunk) => {
    console.log('data')
    chunks.push(chunk)
  })

,输出

o = undefined
data
end

1 个答案:

答案 0 :(得分:0)

1:console.log('o = ' + o)是同步代码,因此它会在您传递给执行异步的f的回调函数streamToString之前运行。因此,当时间console.log('o = ' + o)完成时,f函数尚未执行,这就是o未定义的原因。只需移动回调函数console.log中的f即可获得所需内容。

const f = (str) => {
  o = JSON.parse(str);
  console.log('o = ' + o);
} 

2:readable在整个过程中发出两次,read只发出一次,详见here

相关问题