Разница между response.write и stream.pipe (response) в NodeJS - PullRequest
0 голосов
/ 24 марта 2020

Как я понимаю, "response.write" дает больше контроля над порцией данных, в которую я записываю, в то время как pipe не имеет никакого контроля над порциями.

Я пытаюсь передавать файлы и я не нужно никакого контроля над порцией данных, поэтому рекомендуется go с stream.pipe (response)? Есть ли какое-либо преимущество, например, производительность по сравнению с response.write?

 downloadStream = readBucket.openDownloadStream(trackID)
 downloadStream.on('data', chunk => {
      console.log('chunk');
      res.write(chunk);
    });

    downloadStream.on('error', error => {
      console.log('error occured', error)
      res.sendStatus(500);
    });

    downloadStream.on('end', () => {
      res.end();
    });

Для моего сценария оба кода работают одинаково. Я предпочитаю трубу из-за меньшего количества кода. Есть ли какие-либо преимущества в производительности, эффективность памяти / ввода-вывода с помощью pipe () по сравнению с response.write?

downloadStream= readBucket.openDownloadStream(trackID)
      downloadStream.pipe(res);

1 Ответ

2 голосов
/ 24 марта 2020

.pipe() - это просто готовый способ отправки потока чтения в потоковый поток. Вы, конечно, можете закодировать его вручную, если хотите, но .pipe() обрабатывает несколько вещей для вас.

Я бы предложил, что-то вроде fs.readFile(). Если вы хотите прочитать весь файл в память, fs.readFile() выполняет работу по открытию файла для чтения, чтению всех данных в буфер, закрытию целевого файла и выдаче вам всех данных в конце. Если есть какие-либо ошибки, он гарантирует, что файл, который вы читали, закрывается.

То же самое верно для .pipe(). Он подключается к событиям data, finish и error для вас и просто обрабатывает все это, одновременно передавая данные в наш поток записи. В зависимости от типа Writestream, он также заботится о «завершении» или «закрытии» как потока чтения, так и потока записи, даже если есть ошибки.

И, .pipe() имеет обработку обратного потока, что-то, что ваш код не. Когда вы звоните res.write(), он возвращает логическое значение. Если это логическое значение true, то буфер записи заполнен, и вам не следует снова вызывать res.write(), пока не произойдет событие drain. Обратите внимание, ваш код этого не делает. Итак, .pipe() является более полным, чем то, что многие люди обычно пишут сами.

Единственные ситуации, которые я видел, когда вы обычно выполняете операцию, подобную конвейеру, но вы не можете использовать .pipe() это когда у вас очень нестандартное поведение во время ошибок и вы хотите сделать что-то значительно отличающееся от обработки ошибок по умолчанию. Просто для потоковой передачи данных и завершения обоих входных и выходных потоков, заканчивая оба при ошибке, он делает именно то, что вам нужно, поэтому нет никакой причины кодировать его самостоятельно, когда желаемое поведение уже встроено.

Для моего сценария оба кода работают одинаково. Я предпочитаю трубу из-за меньшего количества кода.

То же самое и здесь.

Есть ли какие-либо преимущества в производительности, эффективность использования памяти / ввода-вывода с pipe () по сравнению с response.write?

Да вроде. Вероятно, в нем меньше ошибок, чем в коде, который вы пишете сами (например, забыли обнаружение обратного потока в вашем примере, которое может появляться только при некоторых обстоятельствах, большие данные, медленное соединение).

...