Skip to content

Commit 2b2ca58

Browse files
author
James Halliday
committed
streams finished
1 parent b6737a6 commit 2b2ca58

File tree

4 files changed

+248
-4
lines changed

4 files changed

+248
-4
lines changed

streams.markdown

+213-4
Original file line numberDiff line numberDiff line change
@@ -273,25 +273,234 @@ into the stream's output.
273273
Use a `VALUE` of `null` to end the stream.
274274

275275
---
276+
# through()
277+
278+
If you don't give through any arguments, these are the
279+
default values for write and end:
280+
281+
* `function write (buf, enc, next) { this.push(buf); next() }`
282+
* `function end () { this.push(null) }`
283+
284+
This means that `through()` with no arguments will pass
285+
everything written as input directly through to its output.
276286

277287
---
278288
# concat-stream
279289

290+
`npm install concat-stream`
291+
292+
concat-stream buffers up all the data in the stream:
293+
294+
```
295+
var concat = require('concat-stream');
296+
process.stdin.pipe(concat(function (body) {
297+
console.log(body.length);
298+
}));
299+
```
300+
301+
You can only write to a concat-stream. You can't read from a
302+
concat-stream.
280303

304+
Keep in mind that all the data will be in memory.
281305

282306
---
283-
# http
307+
# stream types
308+
309+
There are many kinds of streams. We've seen two types
310+
already: transform (through2) and writable (concat-stream).
311+
312+
* readable - produces data: you can pipe FROM it
313+
* writable - consumes data: you can pipe TO it
314+
* transform - consumes data, producing transformed data
315+
* duplex - consumes data separately from producing data
316+
317+
---
318+
# stream types in code
319+
320+
* readable: `readable.pipe(A)`
321+
* writable: `A.pipe(writable)`
322+
* transform: `A.pipe(transform).pipe(B)`
323+
* duplex: `A.pipe(duplex).pipe(A)`
284324

285325
---
286-
# readable
326+
# duplex streams
327+
328+
You can write to and read from a duplex stream, but the
329+
input doesn't directly drive the output.
330+
331+
Duplex streams are like having a conversation on a telephone
332+
where both parties can talk and listen whenever they want.
333+
334+
If you can do:
335+
336+
a.pipe(duplex).pipe(a)
337+
338+
then you have a duplex stream.
287339

288340
---
289-
# writable
341+
# writable stream methods
342+
343+
We've seen `.pipe()` which is a method of all readable
344+
streams (readable, transform, and duplex).
345+
346+
Any stream you can write to (writable, transform, and duplex
347+
streams) has these methods:
348+
349+
* `.write(buf)` - write some data
350+
* `.end()` - close the stream
351+
* `.end(buf)` - write some data and close the stream
352+
353+
---
354+
# core streams in node
355+
356+
* `process.stdin` - readable stream
357+
* `process.stdout` - writable stream
358+
* `process.stderr` - writable stream
359+
* http request object - readable stream
360+
* http response object - writable stream
361+
* net socket - duplex stream
290362

291363
---
292-
# through
293364

294365
```
295366
process.stdin.pipe(process.stdout)
296367
```
297368

369+
---
370+
# http
371+
372+
req is a readable stream, res is a writable stream:
373+
374+
``` js
375+
var http = require('http');
376+
var server = http.createServer(function (req, res) {
377+
req.pipe(process.stdout);
378+
res.end('hello thar!\n');
379+
});
380+
server.listen(5000);
381+
```
382+
383+
---
384+
# net
385+
386+
``` js
387+
var net = require('net');
388+
389+
```
390+
391+
---
392+
# object streams
393+
394+
Normally you can only read and write buffers and strings
395+
with streams. However, if you initialize a stream in
396+
`objectMode`, you can use any kind of object (except for
397+
`null`):
398+
399+
``` js
400+
var through = require('through2');
401+
var tr = through.obj(function (row, enc, next) {
402+
this.push((row.n * 1000) + '\n');
403+
next();
404+
});
405+
tr.pipe(process.stdout);
406+
tr.write({ n: 5 });
407+
tr.write({ n: 10 });
408+
tr.write({ n: 3 });
409+
tr.end();
410+
```
411+
412+
---
413+
output:
414+
415+
``` js
416+
5000
417+
10000
418+
3000
419+
```
420+
421+
---
422+
# duplexer2
423+
424+
Sometimes you'll have a writable stream and a readable
425+
stream, and you'll want to package up both streams into a
426+
single readable+writable duplex stream.
427+
428+
Use `duplexer(writable, readable)` to make a new stream:
429+
430+
``` js
431+
var duplexer = require('duplexer2');
432+
var dup = duplexer(process.stdout, process.stdin);
433+
dup.write('beep boop\n'); // writes beep boop to stdout
434+
dup.pipe(process.stderr); // pipes stdin to stderr
435+
```
436+
437+
---
438+
# split
439+
440+
There is a handy module for splitting a stream into
441+
newlines called split (`npm install split`):
442+
443+
``` js
444+
var split = require('split');
445+
var sp = split();
446+
sp.pipe(through(function (buf, enc, next) {
447+
console.log('line=' + buf);
448+
next();
449+
}));
450+
sp.end('abc\ndef\nghi\n');
451+
```
452+
453+
Even though we wrote a chunk with 3 newlines in it, on the
454+
output side of split we get 3 separate chunks for each line.
455+
456+
---
457+
# stream-combiner2
458+
459+
Similarly to duplexer2, you can combine many streams at once
460+
in a pipeline using `stream-combiner2`. You'll get back a
461+
single stream.
462+
463+
---
464+
465+
``` js
466+
var split = require('split');
467+
var combine = require('stream-combiner2');
468+
var through = require('through2');
469+
470+
var stream = combine(
471+
split(),
472+
through(double),
473+
through(linecount)
474+
);
475+
stream.pipe(process.stdout);
476+
stream.end('abc\ndefghi\nkl');
477+
478+
function double (buf, enc, next) {
479+
this.push(buf + buf + '\n');
480+
next();
481+
}
482+
483+
function linecount (buf, enc, next) {
484+
this.push((buf.length - 1) + '\n');
485+
next();
486+
}
487+
```
488+
489+
---
490+
491+
```
492+
$ node combine.js
493+
6
494+
12
495+
4
496+
```
497+
498+
---
499+
# homework
500+
501+
```
502+
$ npm install -g stream-adventure
503+
```
504+
505+
Then type `stream-adventure`.
506+

streams/combine.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
var split = require('split');
2+
var combine = require('stream-combiner2');
3+
var through = require('through2');
4+
5+
var stream = combine(
6+
split(),
7+
through(double),
8+
through(linecount)
9+
);
10+
stream.pipe(process.stdout);
11+
stream.end('abc\ndefghi\nkl');
12+
13+
function double (buf, enc, next) {
14+
this.push(buf + buf + '\n');
15+
next();
16+
}
17+
18+
function linecount (buf, enc, next) {
19+
this.push((buf.length - 1) + '\n');
20+
next();
21+
}

streams/concat.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
var concat = require('concat-stream');
2+
process.stdin.pipe(concat(function (body) {
3+
console.log(body.length);
4+
}));

streams/obj.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
var through = require('through2');
2+
var tr = through.obj(function (row, enc, next) {
3+
this.push((row.n * 1000) + '\n');
4+
next();
5+
});
6+
tr.pipe(process.stdout);
7+
tr.write({ n: 5 });
8+
tr.write({ n: 10 });
9+
tr.write({ n: 3 });
10+
tr.end();

0 commit comments

Comments
 (0)