Size: a a a

NodeUA - JavaScript and Node.js in Ukraine

2020 December 19

Y

Yevhen in NodeUA - JavaScript and Node.js in Ukraine
Andrey Listochkin
Если Нод свежий, то можно без промисифая:  const { pipeline } = require('stream/promises');
Спасибо!
источник

М

МС Бэнтли in NodeUA - JavaScript and Node.js in Ukraine
Привет, пробовал оба варианта - с пайпом и с пайплайном, нашел еще вариант с stream.finished (он по идее должен лучше мне подходить, потому что доп операций с выгруженным стримом мне проводить не нужно), но он не работает как описано в доке. Изложил все три варианта в коде. Если подскажете что я делаю не так - буду очень благодарен.

https://codesandbox.io/s/dry-cache-c7jf8?file=/src/index.js
источник

М

МС Бэнтли in NodeUA - JavaScript and Node.js in Ukraine
нода у меня 14.15, последняя лтс, а в сендбоксе 10, но все описанные методы поддерживаются с 10ой ноды
источник

М

МС Бэнтли in NodeUA - JavaScript and Node.js in Ukraine
пока для себя решил проблему через юзедж
 await fs.promises.readFile(FILE_PATH) 

но было бы интересно узнать как такие штуки нормально должны хендлиться и почему варианты со стримами не работают
источник

Y

Yevhen in NodeUA - JavaScript and Node.js in Ukraine
МС Бэнтли
Привет, пробовал оба варианта - с пайпом и с пайплайном, нашел еще вариант с stream.finished (он по идее должен лучше мне подходить, потому что доп операций с выгруженным стримом мне проводить не нужно), но он не работает как описано в доке. Изложил все три варианта в коде. Если подскажете что я делаю не так - буду очень благодарен.

https://codesandbox.io/s/dry-cache-c7jf8?file=/src/index.js
Из того, что сразу видно, Вы пишете в WriteStream и не закрываете его (ws.end()). После этого открываете ReadStream на этом же файле, который потенциально еще не записался до конца
источник

Y

Yevhen in NodeUA - JavaScript and Node.js in Ukraine
А Вы пишете в файл и сразу его отдаете с диска для примера или в оригинальном коде такая же логика?
источник

М

МС Бэнтли in NodeUA - JavaScript and Node.js in Ukraine
Yevhen
А Вы пишете в файл и сразу его отдаете с диска для примера или в оригинальном коде такая же логика?
да, логика такая же в оригинальном коде.
вот вы сейчас написали об этом, и я подумал что я в любом случае возвращаю буфер в респонсе, убрал вообще запись в файл через стрим/чтение из файла и использовал writeToBuffer ф-цию из csv либы с тем же результатом (работает ок).

А по поводу закрытия WriteStream - метод библиотеки сам закрывает стрим в конце операции.
источник

Y

Yevhen in NodeUA - JavaScript and Node.js in Ukraine
МС Бэнтли
да, логика такая же в оригинальном коде.
вот вы сейчас написали об этом, и я подумал что я в любом случае возвращаю буфер в респонсе, убрал вообще запись в файл через стрим/чтение из файла и использовал writeToBuffer ф-цию из csv либы с тем же результатом (работает ок).

А по поводу закрытия WriteStream - метод библиотеки сам закрывает стрим в конце операции.
Метод то закрывает, но окончание записи в stream не значит, что получатель успел все вычитать из стрима к тому моменту, как вы начинаете читать файл
источник

Y

Yevhen in NodeUA - JavaScript and Node.js in Ukraine
csv.writeToStream(ws, [{ A: "a", B: "b" }], { headers: true });
Выполнение данной строки не значит, что ws получил все данные и записал их на диск
источник

Y

Yevhen in NodeUA - JavaScript and Node.js in Ukraine
МС Бэнтли
да, логика такая же в оригинальном коде.
вот вы сейчас написали об этом, и я подумал что я в любом случае возвращаю буфер в респонсе, убрал вообще запись в файл через стрим/чтение из файла и использовал writeToBuffer ф-цию из csv либы с тем же результатом (работает ок).

А по поводу закрытия WriteStream - метод библиотеки сам закрывает стрим в конце операции.
А где Вы прочитали, что writeToStream закрывает stream?
Во всех примерах в доке он закрывается явно https://c2fo.io/fast-csv/docs/formatting/examples
источник

Y

Yevhen in NodeUA - JavaScript and Node.js in Ukraine
https://c2fo.io/fast-csv/docs/formatting/methods#writetostream
Write an array of values to a WritableStream, and returns the original stream
источник

М

МС Бэнтли in NodeUA - JavaScript and Node.js in Ukraine
насколько я понимаю, это как раз кейс для использования пайплайна, чтобы убедиться что все прошло получилось и записалось на диск
тип
await pipeline (fs.createWriteStream(...), csv.writeToStream(...), еще операция, и тд)

хм, а когда я пытался его закрыть после метода - мне вылетала ошибка что стрим уже был закрыт
источник

Y

Yevhen in NodeUA - JavaScript and Node.js in Ukraine
А вот из их примера как обернуть в promise
new Promise((res, rej) => {
           writeToStream(stream, rows, options)
               .on('error', (err: Error) => rej(err))
               .on('finish', () => res());
источник

Y

Yevhen in NodeUA - JavaScript and Node.js in Ukraine
МС Бэнтли
насколько я понимаю, это как раз кейс для использования пайплайна, чтобы убедиться что все прошло получилось и записалось на диск
тип
await pipeline (fs.createWriteStream(...), csv.writeToStream(...), еще операция, и тд)

хм, а когда я пытался его закрыть после метода - мне вылетала ошибка что стрим уже был закрыт
А какой Вы stream закрывали? ws или csv?
источник

М

МС Бэнтли in NodeUA - JavaScript and Node.js in Ukraine
ws
ааа, вот оно что
источник

Y

Yevhen in NodeUA - JavaScript and Node.js in Ukraine
В общем, стримы нужно явно закрывать после того, как все записали
источник

Y

Yevhen in NodeUA - JavaScript and Node.js in Ukraine
@teorge А вот код writeToStream, если интересно. Он делает только pipe в тот stream, который ему передают
https://github.com/C2FO/fast-csv/blob/master/packages/format/src/index.ts#L34
источник

Y

Yevhen in NodeUA - JavaScript and Node.js in Ukraine
Вот тут есть диаграмма того как работает pipe https://nodejs.org/en/docs/guides/backpressuring-in-streams/
источник

М

МС Бэнтли in NodeUA - JavaScript and Node.js in Ukraine
Yevhen
@teorge А вот код writeToStream, если интересно. Он делает только pipe в тот stream, который ему передают
https://github.com/C2FO/fast-csv/blob/master/packages/format/src/index.ts#L34
всего то нужно было чуть дольше покопаться в исходниках и доках
понял, спасибо большое, буду изучать
источник

Y

Yevhen in NodeUA - JavaScript and Node.js in Ukraine
МС Бэнтли
всего то нужно было чуть дольше покопаться в исходниках и доках
понял, спасибо большое, буду изучать
Не за что)
Я точно так возился с archiver. Генерировал CSV, добавлял в архив и стримил клиенту. Иногда прилетал битый архив. Разбирался как работают streams, смотрел код archiver.

Кстати, вот еще неплохая статья по streams https://github.com/substack/stream-handbook
источник