Как мне закрыть поток, в котором больше нет данных для отправки в node.js?
Я использую node.js и читаю ввод с последовательного порта, открывая файл /dev/tty, отправляю команду и читаю результат команды и хочу закрыть поток после прочтения и анализа всех данных, Я знаю, что я закончил чтение данных и конец маркера данных. Я обнаружил, что после закрытия потока моя программа не завершается.
Ниже приведен пример того, что я вижу, но использует /dev/random для медленной генерации данных (при условии, что ваша система мало что делает). Я обнаружил, что процесс завершится, как только устройство сгенерирует данные после закрытия потока.
var util = require('util'),
PassThrough = require('stream').PassThrough,
fs = require('fs');
// If the system is not doing enough to fill the entropy pool
// /dev/random will not return much data. Feed the entropy pool with :
// ssh <host> 'cat /dev/urandom' > /dev/urandom
var readStream = fs.createReadStream('/dev/random');
var pt = new PassThrough();
pt.on('data', function (data) {
console.log(data)
console.log('closing');
readStream.close(); //expect the process to terminate immediately
});
readStream.pipe(pt);
Обновление:1
Я вернулся к этой проблеме и имею другой пример, этот просто использует pty и легко воспроизводится в repl узла. Войдите в систему на 2 терминалах и используйте pty терминала, который вы не используете, в приведенном ниже вызове createReadStream.
var fs = require('fs');
var rs = fs.createReadStream('/dev/pts/1'); // a pty that is allocated in another terminal by my user
//wait just a second, don't copy and paste everything at once
process.exit(0);
в этот момент узел просто зависнет и не выйдет. Это на 10.28.
3 ответа
Вместо того, чтобы использовать
readStream.close(),
попробуйте использовать
readStream.pause().
Но, если вы используете новейшую версию узла, оберните поток чтения объектом, созданным из потокового модуля с помощью isaacs, например так:
var Readable = require('stream').Readable;
var myReader = new Readable().wrap(readStream);
и используйте myReader вместо readStream после этого.
Удачи! Скажи мне, если это работает.
я на самом деле подключаюсь к http-запросу.. так что для меня это примерно:
pt.on('close', (chunk) => {
req.abort();
});
Вы закрываете /dev/random
поток, но у вас все еще есть слушатель для 'data'
событие сквозной передачи, которое будет поддерживать работу приложения до тех пор, пока сквозная передача не будет закрыта.
Я предполагаю, что есть некоторые буферизованные данные из потока чтения, и пока это не сброшено, проход не закрыт. Но это всего лишь предположение.
Чтобы получить желаемое поведение, вы можете удалить прослушиватель событий при передаче следующим образом:
pt.on('data', function (data) {
console.log(data)
console.log('closing');
pt.removeAllListeners('data');
readStream.close();
});