Node.js ReadableStream 和异步事件侦听器
Node.js ReadableStream and Asynchronous Event Listeners
有人可以解释以下行为吗?这当然是由于异步 I/O,但下面的代码基于许多简单的示例,其中一些来自 SO,显然这里没有讨论问题,其中流没有按预期读取。
解决方案是什么?我试图从第一原则理解潜在的问题,所以请不要建议我使用已发布的 npm stream->string 包。谢谢。
给定文件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。
我也尝试过 'read' 事件,即
s.on('read', (chunk) => {
console.log('data')
chunks.push(chunk)
})
输出为
o = undefined
data
end
1: console.log('o = ' + o)
是一个同步代码,所以它 运行 在你传递给 streamToString
的回调函数 f
之前是异步执行的。所以当时间 console.log('o = ' + o)
执行时,f
函数还没有执行,这就是 o
未定义的原因。只需将 console.log
移动到回调函数 f
中即可获得您想要的内容。
const f = (str) => {
o = JSON.parse(str);
console.log('o = ' + o);
}
2:readable
全程发出两次,read
只发出一次,详见here
有人可以解释以下行为吗?这当然是由于异步 I/O,但下面的代码基于许多简单的示例,其中一些来自 SO,显然这里没有讨论问题,其中流没有按预期读取。
解决方案是什么?我试图从第一原则理解潜在的问题,所以请不要建议我使用已发布的 npm stream->string 包。谢谢。
给定文件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。
我也尝试过 'read' 事件,即
s.on('read', (chunk) => {
console.log('data')
chunks.push(chunk)
})
输出为
o = undefined
data
end
1: console.log('o = ' + o)
是一个同步代码,所以它 运行 在你传递给 streamToString
的回调函数 f
之前是异步执行的。所以当时间 console.log('o = ' + o)
执行时,f
函数还没有执行,这就是 o
未定义的原因。只需将 console.log
移动到回调函数 f
中即可获得您想要的内容。
const f = (str) => {
o = JSON.parse(str);
console.log('o = ' + o);
}
2:readable
全程发出两次,read
只发出一次,详见here