utilizing bluebird promises

19
Unfullled (Newborn) Promise Fullled (Resolved) Promise Failed (Rejected) Promise Promises Crash Course Nicholas van de Walle

Upload: nicholas-van-de-walle

Post on 15-Jul-2015

133 views

Category:

Engineering


1 download

TRANSCRIPT

Unfulfilled(Newborn)

Promise

Fulfilled (Resolved) Promise

Failed (Rejected) PromisePromises Crash Course

Nicholas van de Walle

13

A resolved promise is essentially a “value”

A rejected promise is essentially a caught ErrorA rejected promise is essentially a caught Error

(error only catches OperationalErrors)

These errors jump straight to the next “catch” or “error”

.catch(fn ( ) { // handlin’})

.catch(fn ( ) { // handlin’});

.then(fn ( ) { // executin’})

.then(fn ( ) { // executin’})

getUserAsync({ userID: ‘abc’})

fn(err) { // handlin’}

fn(err) { // handlin’}

fn(err) { // handlin’}

Promises allow you to create asynchronous “Pipelines”

Sending JSON

fn(err) { // handlin’}

Error Handler(Generic)

Diff ’rent404’d

Puppies Got! … then

Get all the user’s puppies

404’d User Got! … then

Get me the user

Creating Promises(A Contrived Example)

fn x2Later ( num, callback ) { process.nextTick( fn () { callback( num * 2 ) })}

fn x2Async ( num ) { return new Promise( fn ( resolver, rejector ) { x2Later( num, resolver ) })}

Use Promisify(A Contrived Example)

fn x2Later ( num, callback ) { process.nextTick( fn () { callback( num * 2 ) })}

x2Async = Promise.promisify( x2Later )

Just use promisifyAll( Always do this at the root require )

var fs = Promise.promisifyAll(require(‘fs’))

fs.readFileAsync(file)fs.readFile(file, cb)

fs.openAsync(file)fs.open(file, cb)

fs.renameAsync(old, new)fs.rename(old, new, cb)

fs.mkdirAsync(path)fs.mkdir(path, cb)

Wrapping non-compliant API’s is easy

var getUsersAsync = fn ( userIds ) {

return new Promise( fn ( resolve, reject ) {

// Noncompliant API uses an object of callbacks

getUsers( userIds, {

success : fn ( err, data ) {

(err) ? reject(err) : resolve(data.users)

},

error : fn ( status, obj ) {

// TODO (Nicholas): REFACTOR TO BE JSON API COMPLIANT

reject( new Promise.OperationalError( status.description ) )

}

})

})

}

Sometimes you need to wait for two (or more) operations to succeeed

Sending JSON

Do some logic

Join’d promises promise

Users Got! … spread

Join these two GetUser promises

You can easily manage collections of promises

( Also: settle, any, some, props )

all

At least one failed

All Successful

And your functional buddies are here too!

( Also: reduce, each, filter )

map

At least one failed

All Successful

Testing Promises is Easy (With Chai as Promised)( Thanks to Domenic Denicola, now of Google Chrome team )

.should.eventually.equal( )

.should.eventually.equal( )

.should.be.rejectedWith( )

.should.be.rejectedWith( )

Advanced Concepts

Timers

Statefulness &Context

Resource Management

Inspection

Timers let you control when and if a promise fulfills

Timeout

Delay

… is the opposite of ...

Bluebird gives you many helpful inspection methods

reflect

isFulfilled

isRejected

isPending

value

reason

?

?

??

??????

Err

Reflect is a super powerful generic Settle

Promise.props({

"First" : doThingAsync().reflect(),

"Second” : doFailerAsync().reflect(),

"Third" : doSomethingElseAsync().reflect()

}).then…

No matter what

Bind lets you share state, w/0 closures

Bind to

State is passed as ‘this’

Enables Code Reuse

Resource management is totes easy with Using & Disposer

fn getConn() { return pool.getConnAsync() .disposer( fn (conn, promise) { conn.close() })}

using( getConn(), fn(conn) { return conn.queryAsync("…")}).then( fn (rows) { log(rows)})

GC