2017-07-30 11:59:47 +02:00
|
|
|
---
|
2017-08-24 09:13:27 +02:00
|
|
|
title: Node.js streams
|
2017-07-30 11:59:47 +02:00
|
|
|
category: Node.js
|
2017-08-30 13:01:52 +02:00
|
|
|
weight: -1
|
2017-08-30 13:33:17 +02:00
|
|
|
updated: 2017-08-30
|
2017-07-30 11:59:47 +02:00
|
|
|
---
|
|
|
|
|
2017-08-24 09:13:27 +02:00
|
|
|
### Types
|
|
|
|
|
|
|
|
| Stream | Description |
|
|
|
|
| --- | --- |
|
|
|
|
| `Readable` | Data emitter |
|
|
|
|
| `Writable` | Data receiver |
|
|
|
|
| `Transform` | Emitter and receiver |
|
|
|
|
| `Duplex` | Emitter and receiver (independent) |
|
|
|
|
|
|
|
|
See: [Stream](https://nodejs.org/api/stream.html#stream_stream) _(nodejs.org)_
|
|
|
|
|
|
|
|
### Streams
|
|
|
|
|
2017-07-30 11:59:47 +02:00
|
|
|
```js
|
|
|
|
const Readable = require('stream').Readable
|
|
|
|
const Writable = require('stream').Writable
|
|
|
|
const Transform = require('stream').Transform
|
|
|
|
```
|
|
|
|
|
|
|
|
### Piping
|
|
|
|
|
|
|
|
```js
|
2017-08-24 09:13:27 +02:00
|
|
|
clock() // Readable stream
|
|
|
|
.pipe(xformer()) // Transform stream
|
|
|
|
.pipe(renderer()) // Writable stream
|
2017-07-30 11:59:47 +02:00
|
|
|
```
|
|
|
|
|
2017-08-24 09:13:27 +02:00
|
|
|
### Methods
|
2017-07-30 11:59:47 +02:00
|
|
|
|
2017-08-24 09:13:27 +02:00
|
|
|
```js
|
|
|
|
stream.push(/*...*/) // Emit a chunk
|
|
|
|
stream.emit('error', error) // Raise an error
|
|
|
|
stream.push(null) // Close a stream
|
|
|
|
```
|
|
|
|
|
|
|
|
### Events
|
|
|
|
|
|
|
|
```js
|
|
|
|
const st = source()
|
|
|
|
st.on('data', (data) => { console.log('<-', data) })
|
|
|
|
st.on('error', (err) => { console.log('!', err.message) })
|
|
|
|
st.on('close', () => { console.log('** bye') })
|
|
|
|
st.on('finish', () => { console.log('** bye') })
|
|
|
|
```
|
|
|
|
|
|
|
|
Assuming `source()` is a readable stream.
|
|
|
|
|
|
|
|
### Flowing mode
|
|
|
|
|
|
|
|
```js
|
|
|
|
// Toggle flowing mode
|
|
|
|
st.resume()
|
|
|
|
st.pause()
|
|
|
|
```
|
|
|
|
|
|
|
|
```js
|
|
|
|
// Automatically turns on flowing mode
|
|
|
|
st.on('data', /*...*/)
|
|
|
|
```
|
|
|
|
|
|
|
|
Stream types
|
|
|
|
------------
|
|
|
|
{: .-three-column}
|
|
|
|
|
|
|
|
### Readable
|
2017-07-30 11:59:47 +02:00
|
|
|
|
|
|
|
```js
|
|
|
|
function clock () {
|
|
|
|
const stream = new Readable({
|
|
|
|
objectMode: true,
|
2017-08-24 09:13:27 +02:00
|
|
|
read() {}
|
2017-07-30 11:59:47 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
setInterval(() => {
|
|
|
|
stream.push({ time: new Date() })
|
|
|
|
}, 1000)
|
|
|
|
|
|
|
|
return stream
|
|
|
|
}
|
2017-08-24 09:13:27 +02:00
|
|
|
|
|
|
|
// Implement read() if you
|
|
|
|
// need on-demand reading.
|
2017-07-30 11:59:47 +02:00
|
|
|
```
|
|
|
|
|
2017-08-24 09:13:27 +02:00
|
|
|
Readable streams are generators of data. Write data using `stream.push()`.
|
2017-07-30 11:59:47 +02:00
|
|
|
|
2017-08-24 09:13:27 +02:00
|
|
|
### Transform
|
2017-07-30 11:59:47 +02:00
|
|
|
|
|
|
|
```js
|
|
|
|
function xformer () {
|
|
|
|
let count = 0
|
|
|
|
|
|
|
|
return new Transform({
|
|
|
|
objectMode: true,
|
|
|
|
transform: (data, _, done) => {
|
2017-08-24 09:13:27 +02:00
|
|
|
done(null, { ...data, index: count++ })
|
2017-07-30 11:59:47 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2017-08-24 09:13:27 +02:00
|
|
|
Pass the updated chunk to `done(null, chunk)`.
|
|
|
|
|
|
|
|
### Writable
|
2017-07-30 11:59:47 +02:00
|
|
|
|
|
|
|
```js
|
|
|
|
function renderer () {
|
|
|
|
return new Writable({
|
|
|
|
objectMode: true,
|
|
|
|
write: (data, _, done) => {
|
|
|
|
console.log('<-', data)
|
|
|
|
done()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2017-08-24 09:13:27 +02:00
|
|
|
### All together now
|
2017-07-30 11:59:47 +02:00
|
|
|
|
|
|
|
```js
|
2017-08-24 09:13:27 +02:00
|
|
|
clock() // Readable stream
|
|
|
|
.pipe(xformer()) // Transform stream
|
|
|
|
.pipe(renderer()) // Writable stream
|
2017-07-30 11:59:47 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
## Also see
|
2017-08-24 09:13:27 +02:00
|
|
|
{: .-one-column}
|
2017-07-30 11:59:47 +02:00
|
|
|
|
2017-08-24 09:13:27 +02:00
|
|
|
- <https://nodejs.org/api/stream.html>
|
2017-07-30 11:59:47 +02:00
|
|
|
- <https://github.com/substack/stream-handbook>
|