Skip to content

Commit bfc0e3f

Browse files
WilliamConnatsermcollina
authored andcommitted
doc: piping from async generators using pipeline()
PR-URL: #33992 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Robert Nagy <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 7b019fd commit bfc0e3f

File tree

1 file changed

+20
-67
lines changed

1 file changed

+20
-67
lines changed

doc/api/stream.md

Lines changed: 20 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2886,80 +2886,33 @@ readable.on('data', (chunk) => {
28862886

28872887
#### Piping to writable streams from async iterators
28882888

2889-
In the scenario of writing to a writable stream from an async iterator, ensure
2890-
the correct handling of backpressure and errors.
2889+
When writing to a writable stream from an async iterator, ensure correct
2890+
handling of backpressure and errors. [`stream.pipeline()`][] abstracts away
2891+
the handling of backpressure and backpressure-related errors:
28912892

28922893
```js
2893-
const { once } = require('events');
2894-
const finished = util.promisify(stream.finished);
2894+
const { pipeline } = require('stream');
2895+
const util = require('util');
2896+
const fs = require('fs');
28952897

28962898
const writable = fs.createWriteStream('./file');
28972899

2898-
function drain(writable) {
2899-
if (writable.destroyed) {
2900-
return Promise.reject(new Error('premature close'));
2901-
}
2902-
return Promise.race([
2903-
once(writable, 'drain'),
2904-
once(writable, 'close')
2905-
.then(() => Promise.reject(new Error('premature close')))
2906-
]);
2907-
}
2908-
2909-
async function pump(iterable, writable) {
2910-
for await (const chunk of iterable) {
2911-
// Handle backpressure on write().
2912-
if (!writable.write(chunk)) {
2913-
await drain(writable);
2914-
}
2900+
// Callback Pattern
2901+
pipeline(iterator, writable, (err, value) => {
2902+
if (err) {
2903+
console.error(err);
2904+
} else {
2905+
console.log(value, 'value returned');
29152906
}
2916-
writable.end();
2917-
}
2918-
2919-
(async function() {
2920-
// Ensure completion without errors.
2921-
await Promise.all([
2922-
pump(iterable, writable),
2923-
finished(writable)
2924-
]);
2925-
})();
2926-
```
2927-
2928-
In the above, errors on `write()` would be caught and thrown by the
2929-
`once()` listener for the `'drain'` event, since `once()` will also handle the
2930-
`'error'` event. To ensure completion of the write stream without errors,
2931-
it is safer to use the `finished()` method as above, instead of using the
2932-
`once()` listener for the `'finish'` event. Under certain cases, an `'error'`
2933-
event could be emitted by the writable stream after `'finish'` and as `once()`
2934-
will release the `'error'` handler on handling the `'finish'` event, it could
2935-
result in an unhandled error.
2936-
2937-
Alternatively, the readable stream could be wrapped with `Readable.from()` and
2938-
then piped via `.pipe()`:
2939-
2940-
```js
2941-
const finished = util.promisify(stream.finished);
2942-
2943-
const writable = fs.createWriteStream('./file');
2944-
2945-
(async function() {
2946-
const readable = Readable.from(iterable);
2947-
readable.pipe(writable);
2948-
// Ensure completion without errors.
2949-
await finished(writable);
2950-
})();
2951-
```
2952-
2953-
Or, using `stream.pipeline()` to pipe streams:
2954-
2955-
```js
2956-
const pipeline = util.promisify(stream.pipeline);
2957-
2958-
const writable = fs.createWriteStream('./file');
2907+
});
29592908

2960-
(async function() {
2961-
await pipeline(iterable, writable);
2962-
})();
2909+
// Promise Pattern
2910+
const pipelinePromise = util.promisify(pipeline);
2911+
pipelinePromise(iterator, writable)
2912+
.then((value) => {
2913+
console.log(value, 'value returned');
2914+
})
2915+
.catch(console.error);
29632916
```
29642917

29652918
<!--type=misc-->

0 commit comments

Comments
 (0)