#javascript #node.js #stream #child-process
Вопрос:
Мой главный Node.js процесс порождает дочерний процесс. Я хочу общаться с дочерним процессом, отправляя ему данные через его stdin и считывая их из его stdout. Дочерний процесс будет продолжен. Я хочу отправить ему сообщение, затем дождаться ответа, что-то сделать с ответом, а затем продолжить основной процесс. Как мне лучше всего это сделать? Я попробовал следующее:
// I call this function after sending to child's stdin
private async readWaitStream() {
let data = '';
let chunk = '';
while (chunk = this._child.stdout.read()){
data = chunk;
}
// doesn't finish because child process stays running
await finished(this._child.stdout);
return data;
}
Дочерний процесс никогда не заканчивается, и это не работает.
Комментарии:
1. Что такое
finished
?2. Возможно, вы захотите попробовать
for await (const chunk of this._child.stdout) …
Ответ №1:
Просто прослушайте end
событие stdout
, а затем верните данные. Тебе нужно обернуть это в Обещание.
private async readWaitStream() {
return new Promise((resolve) => {
let data = '';
this._child.stdout.on('readable', () => {
let chunk = '';
while (chunk = this._child.stdout.read()) {
data = chunk;
}
});
this._child.stdout.on('end', () => {
resolve(data); // return data
});
});
}
Комментарии:
1. Хм, мне показалось, что это не сработало. Дочерний процесс не закончился, и обещание не было выполнено.
2. @XSeven Обновил логику. Регистрируйте слушателей одновременно.
3. к сожалению, это тоже не сработало для меня. По-прежнему похоже, что stdout дочернего процесса никогда не выдает «конец». Дочерний процесс должен оставаться запущенным и получать более поздние входные данные. Есть ли способ просто дождаться следующей реакции ребенка? @hoangdv
Ответ №2:
Я придумал, как решить эту проблему. Я использую once.('readable' ... )
, например:
private readWaitStream() {
return new Promise(resolve => {
let data = '';
this._child.once('readable', () => {
let chunk = '';
while (chunk = this._child.read()) {
data = chunk;
}
resolve(data);
});
});
}
Когда я then
выполняю функцию, мы будем ждать ввода, и обещание разрешится только после того, как будет доступен следующий ввод.