鉴于我使用nodejs readline库迭代STDIN流中的每一行的情况,对它进行一些处理并将其写回STDOUT,如下例所示:
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
function my_function(line) {
var output = ...(line);
process.stdout.write(output);
}
rl.on('line', my_function);
我担心我正在进行的处理将花费非常不同的时间,具体取决于行内容,因此某些行将很快返回,而其他行需要一些时间来整理。 my_function()
是否可能无序运行,从而导致输出流被扰乱?我应该考虑使用某种同步循环而不是这种异步事件处理程序吗?
答案 0 :(得分:2)
JavaScript执行本身是单线程的,因此只要您只在事件处理程序中执行同步操作,就没有问题。
如果 在事件处理程序中执行异步操作,则可能在异步操作之前发出另一个'line'
事件完成了。在这种情况下,一旦完成异步操作,首先需要rl.pause()
然后rl.resume()
。但是,这并非万无一失,因为如果从输入流中读取的当前数据块有多个换行符,'line'
事件仍可在rl.pause()
之后发出。
因此,如果您在事件处理程序中执行异步操作,那么您最好只是自己从流中读取,以便您可以更好地控制解析行为。这实际上很容易做到,例如:
function parseStream(stream, callback) {
// Assuming all stream data is text and not binary ...
var buffer = '';
var RE_EOL = /\r?\n/g;
stream.on('data', function(data) {
buffer += data;
processBuffer();
});
stream.on('end', callback);
stream.on('error', callback);
function processBuffer() {
var idx = RE_EOL.exec(buffer);
if (~idx) {
// Found a line ending
var line = buffer.slice(0, RE_EOL.index);
buffer = buffer.slice(RE_EOL.index + RE_EOL[0].length);
stream.pause();
callback(null, line, processBuffer);
} else {
stream.resume();
}
}
}
// ...
processStream(process.stdin, function(err, line, done) {
if (err) throw err;
if (line === undefined) {
// No more data will be available (stream ended)
console.log('(Stream ended!)');
return;
}
// Do something with `line`
console.log(line);
// Call `done()` whenever your async operation(s) are all finished
done();
});