2014-10-23 3 views
1

Вот пример кода, который не сильно отличается от того, что вы можете получить от сети или документации:Node read stream: когда происходит потоковое вещание?

var fs = require('fs'); 
var r = fs.createReadStream(process.argv[2], { encoding: 'utf8' }); 
r.on('data', function (chunk) { 
    console.log("chunk: >>>" + chunk + "<<<"); 
}); 
r.on('end', function() { 
    console.log("This is the end"); 
}); 

Что озадачивает меня: когда же потоковое, что триггера события происходят? По-видимому, не прямо на построение потока чтения, потому что тогда это будет сделано, прежде чем мы перейдем к on s, и код прослушивания событий никогда не будет выполнен (что и получается, это работает отлично).

Что меня беспокоит: есть теоретический шанс, что событие пропущено, если on вызов приходит слишком поздно?

ответ

3

Ответ: нет, это не представляется возможным в узле 0.10.x и более поздних версий. Когда поток создается, он приостанавливается, поэтому ни data, ни end события не могут быть выбрасываться. Когда вы добавляете слушателя data (но не end прослушиватель), поток автоматически возобновляется.

Также стоит упомянуть, что IO не может произойти до истечения текущего «галочки», поэтому, если вы присоединяете data, прослушиватели в одном тике всегда безопасны даже для ранних версий узлов. Например:

stream.resume(); 
stream.on('data', ...); // <- same tick, same javascript invocation = safe 

stream.resume(); 
setImmediate(function() { 
    stream.on('data', ...); // <- different tick, different javascript invocation = unsafe 
}); 

Это может показаться странным, но добавление слушателя в process.nextTick обратного вызова также безопасно, потому что это на самом деле вызывается сразу после ТОКА клеща перед любым обратным вызовом IO (случай действительно плохого наименования).

+0

С первого пункта, это звучит как '«end'' событие может все еще быть потеряны, поскольку поток возобновляется, когда я добавить '» data'' слушателя, и может быть завершена, прежде чем я добавить '' end'' слушатель. Я полагаю, что то, что вы говорите во втором абзаце, предотвращает это, если оба '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''' '' '' '' '' '' '' '. Но каковы критерии для двух операторов, которые должны выполняться в одном тике? – njlarsson

+0

Это правильно, если вы добавляете слушателя 'data', но не' end' слушателя, вы можете его пропустить. Обновлен ответ – vkurchatkin

+0

Что меня еще пугает, так это то, что критерии для двух операторов должны выполняться в одном тике. Из вашего примера, я полагаю, что 'on' не делает отметку конца, но' setImmediate' делает. Итак, что именно делает тик? Я тоже не мог найти ответ на этот вопрос, хотя я полагаю, что он существует в некоторых очень длинных и глубоких текстах. – njlarsson

2

Самый простой способ думать о том, что весь код, вы предоставили преграждает поэтому никакой активности не может происходить в потоке до текущего клеща заканчивается, как объясняет vkurchatkin. Только тогда, когда выполнение JavaScript для текущего галочки завершается, начнется инициализация потока ввода-вывода.

var fs = require('fs'); 
var r = fs.createReadStream(process.argv[2], { encoding: 'utf8' }); 
// Stream created in paused state, JS code is blocking IO 

// We're still in the current tick so no IO could have occured since the above lines 
r.on('data', function (chunk) { 
    console.log("chunk: >>>" + chunk + "<<<"); 
}); 

// We're still in the current tick so no IO could have occured since the above lines 
r.on('end', function() { 
    console.log("This is the end"); 
}); 

// We've left the current tick so the internal IO code will now execute and call the bound events if necessary 
+0

Но почему мы оставили текущий тик на последней строке? Критическая точка - это то, что запускает конец тика, если это то, где начинается потоковая передача. – njlarsson

+1

Когда больше событий, связанных с вами, не выполняется. Другими словами, как только все JS-коды завершатся, следующий тик может произойти. Это не может быть идеальным техническим объяснением, но это достаточно, чтобы понять концепцию. – eshortie

+0

«События, которые вы связали», это еще одна терминология, с которой я не знаком.Ну, я понимаю концепцию, я выясню, что именно происходит (в том числе с ожиданиями ввода-вывода и таймерами) в другой раз. – njlarsson

Смежные вопросы