преобразование
Потоки преобразования являются как читаемыми, так и записываемыми, и поэтому являются действительно хорошими «средними» потоками. По этой причине их иногда называют through
потоками. В этом смысле они похожи на дуплексный поток, за исключением того, что они предоставляют удобный интерфейс для манипулирования данными, а не просто для их отправки. Цель потока преобразования состоит в том, чтобы манипулировать данными при их передаче по потоку. Вы можете, например, сделать несколько асинхронных вызовов или получить пару полей, переназначить некоторые вещи и т. Д.
Как создать поток преобразования смотрите здесь и здесь . Все, что вам нужно сделать, это:
- включить модуль потока
- создавать (или наследовать) класс Transform
- реализовать
_transform
метод, который принимает (chunk, encoding, callback)
.
Кусок - это ваши данные. Большую часть времени вам не нужно беспокоиться о кодировании, если вы работаете в objectMode = true
. Обратный вызов вызывается, когда вы закончите обработку чанка. Этот кусок затем передается следующему потоку.
Если вам нужен хороший вспомогательный модуль, который позволит вам действительно легко выполнять потоковую передачу , я предлагаю использовать via2 .
Для обработки ошибок, продолжайте читать.
труба
В цепочке труб обработка ошибок действительно нетривиальна. Согласно этой теме .pipe () не создан для пересылки ошибок. Так что-то вроде ...
var a = createStream();
a.pipe(b).pipe(c).on('error', function(e){handleError(e)});
... будет только слушать ошибки в потоке c
. Если произошла ошибка a
, она не будет передана и, на самом деле, выдастся. Чтобы сделать это правильно:
var a = createStream();
a.on('error', function(e){handleError(e)})
.pipe(b)
.on('error', function(e){handleError(e)})
.pipe(c)
.on('error', function(e){handleError(e)});
Теперь, хотя второй способ более многословен, вы можете, по крайней мере, сохранить контекст, где происходят ваши ошибки. Обычно это хорошая вещь.
Одна библиотека, которую я нахожу полезной, хотя, если у вас есть случай, когда вы хотите захватить только ошибки в месте назначения, и вас не волнует, где это произошло, это поток событий .
конец
Когда происходит событие ошибки, событие завершения не будет запущено (явно). Излучение события ошибки завершит поток.
домены
По моему опыту, домены работают очень хорошо большую часть времени. Если у вас есть необработанное событие ошибки (т.е. выдается ошибка в потоке без прослушивателя), сервер может дать сбой. Теперь, как указано в приведенной выше статье, вы можете заключить поток в домен, который должен правильно отлавливать все ошибки.
var d = domain.create();
d.on('error', handleAllErrors);
d.run(function() {
fs.createReadStream(tarball)
.pipe(gzip.Gunzip())
.pipe(tar.Extract({ path: targetPath }))
.on('close', cb);
});
Прелесть доменов в том, что они сохранят следы стека. Хотя Event-Stream также хорошо справляется с этой задачей.
Для дальнейшего чтения, ознакомьтесь со справочником . Довольно подробно, но очень полезно и дает отличные ссылки на множество полезных модулей.
Promise
рамки делают это намного проще