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();
});
感謝您的解釋和建議如何繼續。坦率地說,儘管我對這個模板的轉換程度有點不安,但它只是一次一行地遍歷一條流。我認爲我有點習慣Unix操作系統的普通操作。我想知道如果我在其他方面的迭代中做得更好,並且一次只對這個特定的腳本進行一次調用。這將是很多的調用,但考慮到庫的開銷,我實際上正在做的解析不會那麼重要。 – Caleb
你能澄清一點嗎?你說過運行'rl.pause()'「並非萬無一失」,但是如果我嚴格遵守那個事件處理程序中的同步函數調用呢?如果我沒有做任何事情,我是否足夠安全地使用我的代碼? – Caleb
如果你只做同步操作,你不必擔心改變什麼,因爲js是單線程的,這意味着當你的事件處理函數被執行時,沒有其他的js可以被執行。這意味着不需要暫停/恢復readline實例或輸入流。但是如果你做過異步操作,你可能會需要類似我給出的代碼示例。 – mscdex