1 of 14

Nodeschool

Flow control with Streams & Promises

2 of 14

Trainers

Sequoia McDowell @_sequoia

Andrew Pasquale @apasquale

Jason Woofenden jasonwoof.com

Sponsors

3 of 14

Goals

  • Streams: what, why, how, where
  • Promises: what, why, how, where
  • Hands-on experience with one or both

4 of 14

Streams: What are they?

  • Objects that implement a stream interface
    • Readable: process.stdin, http.IncomingMessage
    • Writable: process.stdout, http.ServerResponse
    • Duplex: net.Socket (tcp socket)
    • Transform: zlib.Gzip, zlib.Gunzip

  • Event emitters. some main events...
    • data [readable] a new chunk of data is available
    • finished [writable] - writing has finished
    • end [readable] - there’s no more data to read

5 of 14

How are they different from any other event emitter?

  • Shared interface with utility methods to pause, resume, & redirect data
  • In particular: pipe

6 of 14

Pipe

var filestream = fs.createReadStream(‘1337.zip’) filestream //readable

.pipe(decryptor) //transform

.pipe(decompressor) //transform

.pipe(parser) //transform

.pipe(process.stdout); //writable

$ decrypt l337.zip | gunzip | parse.sh

# implicitly “pipe” parse.sh to stdout

7 of 14

Streams: How do they work?

readablez.pipe(transformer).pipe(process.stdout)

  • .pipe pulls data from readablez, writes it to transformer
  • transformer._write called when readables emits data
  • transformer transforms the data chunk
  • transformer emits that transformed chunk
  • .pipe sends data emitted from transformer to process.stdout._write
  • data appears in terminal (or wherever stdout is pointed)

8 of 14

Why use it

  • Fast
  • Less memory overhead
  • Composable

9 of 14

Promises: What are they

  • Object that represents data that will be available at some point in the future
  • Provides a then method
    • Then takes functions to run on fulfillment or rejection of promise
  • Used to write async code in a synchronous style
  • Used to make async control flow more clear

10 of 14

Callbacks

Promises

doAsync1(function(){

doAsync2(function(){

doAsync3(function(){

doAsync4(function(){

});

});

});

doAsync1()

.then(doAsync2)

.then(doAsync3)

.then(doAsync4);

11 of 14

Usage

printfile(name, callback){

readFile(arg.name, function(contents){

console.log(contents);

});

};

printfile(name){

promise = new Promise();

readFile(arg.name, function(contents){

promise.resolve(contents)

});

return promise;

};

12 of 14

How do we get to that second version?

printfile(name, callback){

readFile(arg.name, function(contents){

console.log(contents);

});

};

getfilecontents(name){

promise = new Promise();

readFile(arg.name, function(contents){

promise.resolve(contents)

});

return promise;

};

13 of 14

How do we get to that second version?

db.getUser(123) //--> user obj

//pass user obj to...

.then(getPrefs) //--> filename

//pass filename to...

.then(getFileContents) //--> contents

//pass contents to...

.then(console.log);

14 of 14

Getting started

install a lesson from nodeschool.io:� npm i -g stream-adventure npm i -g promise-it-wont-hurt

Resources

Sequoia: @_sequoia

Andrew: @apasquale

Jason: jasonwoof.com