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

Utilizing Bluebird Promises

Embed Size (px)

Citation preview

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