SlideShare a Scribd company logo
Promises
Asynchronous Control Flow
A long time ago in a galaxy far far away...
The problem
Q: How to control the asynchronous flow of your
application when there are dependencies between
two steps?
A: I can use Callbacks :)
function asyncFunction1(function (err, result) {
// do something here...
asyncFuncion2(function (err2, result2) {
// other stuff here...
})
})
However… Callbacks can get ugly
module.exports.verifyPassword = function(user, password, done) {
if(typeof password !== ‘string’) {
done(new Error(‘password should be a string’))
}
computeHash(password, user.passwordHashOpts, function(err, hash) {
if(err) {
done(err)
}
done(null, hash === user.passwordHash)
})
}
Callback being called multiple times
This one is easily fixed though...
module.exports.verifyPassword = function(user, password, done) {
if(typeof password !== ‘string’) {
return done(new Error(‘password should be a string’))
}
computeHash(password, user.passwordHashOpts, function(err, hash) {
if(err) {
return done(err)
}
return done(null, hash === user.passwordHash)
})
}
Always return when calling the callback
Q: How execute asynchronous function in
parallel and proceed when all have finished?
But what about parallel execution?
var finished = [false, false]
function asyncFunction1(function (err, result) {
// do some stuff
finished[0] = true
if (finished[0] === true && finished[1] === true) {
// proceed…
}
})
function asyncFunction2(function (err, result) {
// do some other stuff
finished[1] = true
if (finished[0] === true && finished[1] === true) {
// proceed…
}
})
The callback hell
Find a better way you must...
The good ol’ async¹ module
async.waterfall([
function(callback) {
callback(null, 'one', 'two');
},
function(arg1, arg2, callback) {
// arg1 = 'one' and arg2 = 'two'
callback(null, 'three');
},
function(arg1, callback) {
// arg1 = 'three'
callback(null, 'done');
}
], function (err, result) {
// result now equals 'done'
});
async.parallel([
function(callback){
setTimeout(function(){
callback(null, 'one');
}, 200);
},
function(callback){
setTimeout(function(){
callback(null, 'two');
}, 100);
}
],
// optional callback
function(err, results){
// the results array will equal ['one','two']
even though
// the second function had a shorter timeout.
});
¹ https://github.com/caolan/async
But it can get cumbersome too...
What if I need to pass an argument to the first
function in the waterfall?
async.waterfall([
async.apply(myFirstFunction, 'zero'),
mySecondFunction,
myLastFunction,
], function (err, result) {
// result = 'done'
});
function myFirstFunction(arg1, callback) {
// arg1 now equals 'zero'
callback(null, 'one', 'two');
}
function mySecondFunction(arg1, arg2, callback) {
// arg1 = 'one' and arg2 = 'two'
callback(null, 'three');
}
function myLastFunction(arg1, callback) {
// arg1 = 'three'
callback(null, 'done');
}
DRY*
Error handling can be tiresome…
You have to bubble your errors up in every layer of
code you have.
And if you forget doing so, a wild bug may appear...
* Don’t Repeat Yourserlf
async.waterfall([
function(callback) {
doSomething(function(err, result){
if (err) return callback(err)
callback(null, result, 'another-thing');
})
},
function(arg1, arg2, callback) {
doAnotherStuff(function(err, result){
if (err) return callback(err)
callback(null, result);
})
},
function(arg1, callback) {
doAnotherStuff(function(err, result){
if (err) return callback(err)
callback(null, result);
})
}
], function (err, result) {
// result now equals 'done'
});
Bug used “confusion”.
It was very effective.
Promises F.T.W.
What is a promise?
The core idea behind promises is that it represents the result of an asynchronous
operation. A promise is in one of three different states:
- Pending: The initial state of a promise.
- Fulfilled: The state of a promise representing a successful operation.
- Rejected: The state of a promise representing a failed operation.
How does a promise work?
The State Diagram of a promise is as simple as this one:
Clarifying a little bit
- When pending, a promise:
○ may transition to either the fulfilled or rejected state.
- When fulfilled, a promise:
○ must not transition to any other state.
○ must have a value, which must not change.
- When rejected, a promise:
○ must not transition to any other state.
○ must have a reason, which must not change.
The “then” method
The “then” method is called when a promise is
either fulfilled or rejected.
This two conditions are treated by different
callbacks:
promise.then(onFulfilled, onRejected)
- onFulfilled(value): value of fulfilment of the
promise as its first argument
- onRejected(reason): reason of rejection of
the promise as its first argument. This
argument is optional.
functionReturningPromise.then(function(value){
// do something with value
}, function (reason) {
// do something if failed
})
Promise chaining
The “then” method always returns a new promise,
so it can be chained.
Even if your callbacks return a value, the promise
implementation will wrap it into a brand new
promise before returning it.
functionReturningPromise.then(function(value){
return 10
})
.then(function (number) {
console.log(number) // 10
})
.then(...)
.then(...)
.then(...)
.then(...)
.then(...)
// The chaining can go indefinetly
Error handling
If any error is thrown within a then callback, a
rejected promise will be automatically returned
with the error as its reason.
The immediately after then call will only execute
the onRejected callback.
If onRejected is not provided or is not a function,
the error will be passed to the next chained then.
If no then call in the chain have a onRejected
callback, the error will be thrown to the main code.
functionReturningPromise.then(function(value){
throw new Error(‘Something bad happened’)
})
.then(function (someArg) {
// do nothing
}, function (reason) {
console.log(reason) // Error: Something …
return 42 // Will return a resolved promise
})
Error bubbling
If onRejected is not provided or is not a function,
the error will be passed to the next chained then.
If the next chained then has the onRejected
callback, it will be called, giving you a possibility of
dealing with the error.
IMPORTANT: if you don’t throw a new error or
re-throw the error argument, the then method will
return a promise that is resolved with the return
value of the onRejected callback.
If no then call in the chain have a onRejected
callback, the error will be thrown to the main code.
functionReturningPromise.then(function(value){
throw new Error(‘Something bad happened’)
})
.then(function (number) {
console.log(number) // Will be bypassed
})
.then(function (someArg) {
// do nothing
}, function (reason) {
console.log(reason) // Error: Something …
// Will return a resolved promise
})
.then(function (number) {
console.log(number)
// undefined because the previous
// callback doesn’t return a value
})
Error catching
In most situations, you only want to deal with
possible errors once.
You can do this by adding a then call at the end of
your chain with only the onRejected callback.
This way, any subsequent then call after the error
throwing will be bypassed and the error will only
be handled by the last one.
Since the last then call is only for error catching,
you don’t need to set a onResolved callback and may
use null instead.
functionReturningPromise.then(function(value){
throw new Error(‘Something bad happened’)
})
.then(function (...) {
// Will be bypassed
})
.then(function (...) {
// Will be bypassed
})
.then(function (...) {
// Will be bypassed
})
.then(null, function (error) {
// Error: Something …
console.log(error)
})
Promises A+
Standardization
Promise A+¹ is a standard specification for promise
implementations.
It allows interoperability between different
promise libraries.
You don’t need to worry about what
implementation of promise a 3rd party module
uses, you can seamlessly integrate it into your code,
as long as it respects the A+ specs.
The specs are at the same time powerful and dead
simple: less than 100 lines of text in plain English.
¹ https://promisesaplus.com/
someLibrary.methodReturningPromise()
.then(function (result) {
return anotherLibrary.anotherPromise()
})
.then(function (anotherResult) {
// ...
})
I mean, a de facto standard...
Promises are now part of the core¹ of EcmaScript 6
(ES6).
That means it is available as part of the standard
library of modern Javascript engines:
● Node.js >= v0.12.*
● Any modern and updated browser (Firefox,
Chrome, Safari, Edge, etc. -- NOT IE)
¹ https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
² http://caniuse.com/#feat=promises
²
Enhancing Promises
Parallel execution
Most of the promise implementations (including
the core one in ES6) have some extra methods will
allow you to have asynchronous code running in
parallel.
The Promise.all¹ method will take an array of
promises as an argument and will return a promise
that will only be resolved when and if all the input
promises are resolved.
The Promise.race¹ method will also take an array of
promises, but will return a promise that resolves to
the value of the first of the input to be resolved.
Promise.all([promise1, promise2, promise3])
.then(function (result) {
// result will be an array with the values
// of the input promises.
// The order is preserved, so you’ll have:
// [resPromise1, resPromise2, resPromise3]
})
Promise.race([promise1, promise2, promise3])
.then(function (result) {
// result will be the either resPromise1,
// resPromise2 or resPromise3, depending
// on which promise finishes firt
})
¹ Not part of the Promise A+ specification
The catch method
The catch¹ method is just a syntactic sugar around
the last-then-treats-error pattern discussed before.
functionReturningPromise.then(function(value){
throw new Error(‘Something bad happened’)
})
.then(null, function (error) {
console.log(error)
})
// Can be rewritten as following in most
// implementations of Promise:
functionReturningPromise.then(function(value){
throw new Error(‘Something bad happened’)
})
.catch(function (error) {
console.log(error)
})
¹ Not part of the Promise A+ specification
Creating settled promises
Another syntactic sugar allows you to create
promises that are already fulfilled or rejected,
through the helper methods Promise.resolve and
Promise.reject.
This can be very useful in cases that your interface
states you should return a promise, but you already
have the value to return (ex.: caching).
var cache = {}
functionReturningPromise.then(function(value){
throw new Error(‘Something bad happened’)
})
.then(function (result) {
if (cache[result] !== undefined) {
return Promise.resolve(cache[result])
} else {
return getFreshData(result)
.then(function (data) {
cache[result] = data
return data
)}
}
})
¹ This is not part of the Promise A+ specification
Non-standard¹ cool extras
The finally method allows you to have a callback
that will be executed either if the promise chain is
resolved or rejected.
The tap method is a really useful syntactic sugar
that allows you to intercept the result of a promise,
but automatically passing it down the chain.
The props method is like Promise.all, but resolves
to an object instead of an array.
db.connect() // Implemented using bluebird
.then(function() {
// run some queries
})
.finally(function () {
// no matter what, close the connection
db.disconnect()
})
var Promise = require('bluebird')
Promise.resolve(42)
// will print 42 into the console and return it
.tap(console.log.bind(console))
.then(function (result) {
// result is still 42
})
Promise.props({ a: getA(), b : getB()})
.then(function (obj) {
// Will print { a : …, b : … }
console.log(obj)
})
¹ Based on Bluebird (http://bluebirdjs.com/docs/) -- a full-featured promise implementation
Promisify all the things!
Converting callback-based code
Bluebird¹ has some utility methods that will adapt
callback-based functions and libs to use promises.
The Promise.promisify method will take any
error-first callback and return a promise that will
be resolved if the callback is called without error or
rejected otherwise.
The Promise.promisifyAll method will take an
objects and iterate over all it’s methods and create
a new implementation of them, keeping the same
name, suffixed by “Async”.
Var Promise = require('bluebird’)
var fs = require('fs')
var readFileAsync = Promise.promisify(fs.readFile)
readFileAsync('someFile.ext')
.then(function (contents) {
// do something
})
// or...
Promise.promisifyAll(fs)
fs.readFileAsync('someFile.ext')
.then(function (contents) {
// do something
})
¹ http://bluebirdjs.com/
A-a-any d-d-doubts?
@hjpbarcelos
henriquebarcelos
Henrique José Pires Barcelos
Fullstack Software Engineer @ Revmob
About the author

More Related Content

What's hot

JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
Colin DeCarlo
 
Getting Comfortable with JS Promises
Getting Comfortable with JS PromisesGetting Comfortable with JS Promises
Getting Comfortable with JS Promises
Asa Kusuma
 
JavaScript Best Pratices
JavaScript Best PraticesJavaScript Best Pratices
JavaScript Best Pratices
ChengHui Weng
 
JavaScript promise
JavaScript promiseJavaScript promise
JavaScript promise
eslam_me
 
Serious Sam shooter anniversary - finding bugs in the code of the Serious Eng...
Serious Sam shooter anniversary - finding bugs in the code of the Serious Eng...Serious Sam shooter anniversary - finding bugs in the code of the Serious Eng...
Serious Sam shooter anniversary - finding bugs in the code of the Serious Eng...
PVS-Studio
 
JavaScript Loop: Optimization of Weak Typing
JavaScript Loop: Optimization of Weak TypingJavaScript Loop: Optimization of Weak Typing
JavaScript Loop: Optimization of Weak Typing
Janlay Wu
 
Control structures
Control structuresControl structures
Control structures
Isha Aggarwal
 
[C++]3 loop statement
[C++]3 loop statement[C++]3 loop statement
[C++]3 loop statement
Junyoung Jung
 
A Spin-off: Firebird Checked by PVS-Studio
A Spin-off: Firebird Checked by PVS-StudioA Spin-off: Firebird Checked by PVS-Studio
A Spin-off: Firebird Checked by PVS-Studio
Andrey Karpov
 
Introduction to Asynchronous scala
Introduction to Asynchronous scalaIntroduction to Asynchronous scala
Introduction to Asynchronous scala
Stratio
 
LinkedIn TBC JavaScript 100: Functions
 LinkedIn TBC JavaScript 100: Functions LinkedIn TBC JavaScript 100: Functions
LinkedIn TBC JavaScript 100: Functions
Adam Crabtree
 
Completable future
Completable futureCompletable future
Completable future
Srinivasan Raghvan
 
Using Akka Futures
Using Akka FuturesUsing Akka Futures
Using Akka Futures
Knoldus Inc.
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
Derek Willian Stavis
 
Cocoa heads 09112017
Cocoa heads 09112017Cocoa heads 09112017
Cocoa heads 09112017
Vincent Pradeilles
 
Pro Java Fx – Developing Enterprise Applications
Pro Java Fx – Developing Enterprise ApplicationsPro Java Fx – Developing Enterprise Applications
Pro Java Fx – Developing Enterprise Applications
Stephen Chin
 
Exporter Proxy
Exporter ProxyExporter Proxy
Exporter Proxy
Workhorse Computing
 
Ownership System in Rust
Ownership System in RustOwnership System in Rust
Ownership System in Rust
Chih-Hsuan Kuo
 
C# Asynchronous delegates
C# Asynchronous delegatesC# Asynchronous delegates
C# Asynchronous delegates
Prem Kumar Badri
 
Code generation with javac plugin
Code generation with javac pluginCode generation with javac plugin
Code generation with javac plugin
Oleksandr Radchykov
 

What's hot (20)

JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
 
Getting Comfortable with JS Promises
Getting Comfortable with JS PromisesGetting Comfortable with JS Promises
Getting Comfortable with JS Promises
 
JavaScript Best Pratices
JavaScript Best PraticesJavaScript Best Pratices
JavaScript Best Pratices
 
JavaScript promise
JavaScript promiseJavaScript promise
JavaScript promise
 
Serious Sam shooter anniversary - finding bugs in the code of the Serious Eng...
Serious Sam shooter anniversary - finding bugs in the code of the Serious Eng...Serious Sam shooter anniversary - finding bugs in the code of the Serious Eng...
Serious Sam shooter anniversary - finding bugs in the code of the Serious Eng...
 
JavaScript Loop: Optimization of Weak Typing
JavaScript Loop: Optimization of Weak TypingJavaScript Loop: Optimization of Weak Typing
JavaScript Loop: Optimization of Weak Typing
 
Control structures
Control structuresControl structures
Control structures
 
[C++]3 loop statement
[C++]3 loop statement[C++]3 loop statement
[C++]3 loop statement
 
A Spin-off: Firebird Checked by PVS-Studio
A Spin-off: Firebird Checked by PVS-StudioA Spin-off: Firebird Checked by PVS-Studio
A Spin-off: Firebird Checked by PVS-Studio
 
Introduction to Asynchronous scala
Introduction to Asynchronous scalaIntroduction to Asynchronous scala
Introduction to Asynchronous scala
 
LinkedIn TBC JavaScript 100: Functions
 LinkedIn TBC JavaScript 100: Functions LinkedIn TBC JavaScript 100: Functions
LinkedIn TBC JavaScript 100: Functions
 
Completable future
Completable futureCompletable future
Completable future
 
Using Akka Futures
Using Akka FuturesUsing Akka Futures
Using Akka Futures
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
Cocoa heads 09112017
Cocoa heads 09112017Cocoa heads 09112017
Cocoa heads 09112017
 
Pro Java Fx – Developing Enterprise Applications
Pro Java Fx – Developing Enterprise ApplicationsPro Java Fx – Developing Enterprise Applications
Pro Java Fx – Developing Enterprise Applications
 
Exporter Proxy
Exporter ProxyExporter Proxy
Exporter Proxy
 
Ownership System in Rust
Ownership System in RustOwnership System in Rust
Ownership System in Rust
 
C# Asynchronous delegates
C# Asynchronous delegatesC# Asynchronous delegates
C# Asynchronous delegates
 
Code generation with javac plugin
Code generation with javac pluginCode generation with javac plugin
Code generation with javac plugin
 

Viewers also liked

Уроки "Основи здров’я" у 3 класі Брагинівської ЗОШ І-ІІІ ступенів класовод Па...
Уроки "Основи здров’я" у 3 класі Брагинівської ЗОШ І-ІІІ ступенів класовод Па...Уроки "Основи здров’я" у 3 класі Брагинівської ЗОШ І-ІІІ ступенів класовод Па...
Уроки "Основи здров’я" у 3 класі Брагинівської ЗОШ І-ІІІ ступенів класовод Па...
gumenuk111
 
Collaborative platformin the agricultural sectorin Algeria. Towards a Knowled...
Collaborative platformin the agricultural sectorin Algeria. Towards a Knowled...Collaborative platformin the agricultural sectorin Algeria. Towards a Knowled...
Collaborative platformin the agricultural sectorin Algeria. Towards a Knowled...
Zakład Systemów Informacyjnych, Instytut Informacji Naukowej i Studiów Bibliologicznych (UW)
 
презентація досвіду роботи
презентація досвіду роботипрезентація досвіду роботи
презентація досвіду роботи
Ірина Гаврилюк
 
44030397 model-pembelajaran-ctl
44030397 model-pembelajaran-ctl44030397 model-pembelajaran-ctl
44030397 model-pembelajaran-ctl
Merviany
 
Power point
Power pointPower point
Power point
santoshthote
 
Lat uts bahasa xi
Lat uts bahasa xiLat uts bahasa xi
Lat uts bahasa xi
Bunga Tupperware
 
Topiki istoria-Βιωματικές Δράσεις Γ΄ Γυμνασίου
Topiki istoria-Βιωματικές Δράσεις Γ΄ ΓυμνασίουTopiki istoria-Βιωματικές Δράσεις Γ΄ Γυμνασίου
Topiki istoria-Βιωματικές Δράσεις Γ΄ Γυμνασίου
Kiki Sakka
 
Ppt ctl dan paikem
Ppt ctl dan paikemPpt ctl dan paikem
Ppt ctl dan paikem
Khusnul Kotimah
 
How To Use Google Calendar
How To Use Google CalendarHow To Use Google Calendar
How To Use Google Calendar
Ardanette Seguban
 
Humidification
HumidificationHumidification
Humidification
Manish Masih
 
Trono dr facilier
Trono dr facilierTrono dr facilier
Trono dr facilier
Paula Dominguez
 
MADESOL | MADERAS
MADESOL | MADERAS MADESOL | MADERAS
MADESOL | MADERAS
michelledm118
 
Diseño de Ottoman : MAHI
Diseño de Ottoman : MAHI Diseño de Ottoman : MAHI
Diseño de Ottoman : MAHI
izabelladominguez18
 
Mueble multifuncional
Mueble multifuncionalMueble multifuncional
Mueble multifuncional
carlaparadas
 
Mueble multifuncional
Mueble multifuncionalMueble multifuncional
Mueble multifuncional
mariaeugeniact12
 
Mueble multifuncional
Mueble multifuncionalMueble multifuncional
Mueble multifuncional
izabelladominguez18
 
Ottoman RGDM-03
Ottoman  RGDM-03Ottoman  RGDM-03
Ottoman RGDM-03
raffaella grisolia
 
Elmer figueroa arce alias chayanne presentacion
Elmer figueroa arce alias chayanne presentacionElmer figueroa arce alias chayanne presentacion
Elmer figueroa arce alias chayanne presentacion
paolatezanos
 

Viewers also liked (19)

Уроки "Основи здров’я" у 3 класі Брагинівської ЗОШ І-ІІІ ступенів класовод Па...
Уроки "Основи здров’я" у 3 класі Брагинівської ЗОШ І-ІІІ ступенів класовод Па...Уроки "Основи здров’я" у 3 класі Брагинівської ЗОШ І-ІІІ ступенів класовод Па...
Уроки "Основи здров’я" у 3 класі Брагинівської ЗОШ І-ІІІ ступенів класовод Па...
 
Collaborative platformin the agricultural sectorin Algeria. Towards a Knowled...
Collaborative platformin the agricultural sectorin Algeria. Towards a Knowled...Collaborative platformin the agricultural sectorin Algeria. Towards a Knowled...
Collaborative platformin the agricultural sectorin Algeria. Towards a Knowled...
 
презентація досвіду роботи
презентація досвіду роботипрезентація досвіду роботи
презентація досвіду роботи
 
44030397 model-pembelajaran-ctl
44030397 model-pembelajaran-ctl44030397 model-pembelajaran-ctl
44030397 model-pembelajaran-ctl
 
Power point
Power pointPower point
Power point
 
Lat uts bahasa xi
Lat uts bahasa xiLat uts bahasa xi
Lat uts bahasa xi
 
Topiki istoria-Βιωματικές Δράσεις Γ΄ Γυμνασίου
Topiki istoria-Βιωματικές Δράσεις Γ΄ ΓυμνασίουTopiki istoria-Βιωματικές Δράσεις Γ΄ Γυμνασίου
Topiki istoria-Βιωματικές Δράσεις Γ΄ Γυμνασίου
 
Πολυμέρης - Βιωματικές Δράσεις και ΤΠΕ
Πολυμέρης - Βιωματικές Δράσεις και ΤΠΕΠολυμέρης - Βιωματικές Δράσεις και ΤΠΕ
Πολυμέρης - Βιωματικές Δράσεις και ΤΠΕ
 
Ppt ctl dan paikem
Ppt ctl dan paikemPpt ctl dan paikem
Ppt ctl dan paikem
 
How To Use Google Calendar
How To Use Google CalendarHow To Use Google Calendar
How To Use Google Calendar
 
Humidification
HumidificationHumidification
Humidification
 
Trono dr facilier
Trono dr facilierTrono dr facilier
Trono dr facilier
 
MADESOL | MADERAS
MADESOL | MADERAS MADESOL | MADERAS
MADESOL | MADERAS
 
Diseño de Ottoman : MAHI
Diseño de Ottoman : MAHI Diseño de Ottoman : MAHI
Diseño de Ottoman : MAHI
 
Mueble multifuncional
Mueble multifuncionalMueble multifuncional
Mueble multifuncional
 
Mueble multifuncional
Mueble multifuncionalMueble multifuncional
Mueble multifuncional
 
Mueble multifuncional
Mueble multifuncionalMueble multifuncional
Mueble multifuncional
 
Ottoman RGDM-03
Ottoman  RGDM-03Ottoman  RGDM-03
Ottoman RGDM-03
 
Elmer figueroa arce alias chayanne presentacion
Elmer figueroa arce alias chayanne presentacionElmer figueroa arce alias chayanne presentacion
Elmer figueroa arce alias chayanne presentacion
 

Similar to Promises - Asynchronous Control Flow

Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
Piotr Pelczar
 
Asynchronous development in JavaScript
Asynchronous development  in JavaScriptAsynchronous development  in JavaScript
Asynchronous development in JavaScript
Amitai Barnea
 
Node js
Node jsNode js
Node js
LearningTech
 
Avoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promisesAvoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promises
Ankit Agarwal
 
Promises & limbo
Promises & limboPromises & limbo
Promises & limbo
Sylvain Faucherand
 
Angular promises and http
Angular promises and httpAngular promises and http
Angular promises and http
Alexe Bogdan
 
You promise?
You promise?You promise?
You promise?
IT Weekend
 
Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016
Codemotion
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)
Domenic Denicola
 
Asynchronous JavaScript Programming with Callbacks & Promises
Asynchronous JavaScript Programming with Callbacks & PromisesAsynchronous JavaScript Programming with Callbacks & Promises
Asynchronous JavaScript Programming with Callbacks & Promises
Hùng Nguyễn Huy
 
AngularJS, More Than Directives !
AngularJS, More Than Directives !AngularJS, More Than Directives !
AngularJS, More Than Directives !
Gaurav Behere
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
jnewmanux
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
Ara Pehlivanian
 
Nevyn — Promise, It's Async! Swift Language User Group Lightning Talk 2015-09-24
Nevyn — Promise, It's Async! Swift Language User Group Lightning Talk 2015-09-24Nevyn — Promise, It's Async! Swift Language User Group Lightning Talk 2015-09-24
Nevyn — Promise, It's Async! Swift Language User Group Lightning Talk 2015-09-24
Joachim Bengtsson
 
Async History - javascript
Async History - javascriptAsync History - javascript
Async History - javascript
Nishchit Dhanani
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation Javascript
Ramesh Nair
 
JavaScript Interview Questions 2023
JavaScript Interview Questions 2023JavaScript Interview Questions 2023
JavaScript Interview Questions 2023
Laurence Svekis ✔
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
Chris Saylor
 
Better react/redux apps using redux-saga
Better react/redux apps using redux-sagaBetter react/redux apps using redux-saga
Better react/redux apps using redux-saga
Younes (omar) Meliani
 
[2015/2016] JavaScript
[2015/2016] JavaScript[2015/2016] JavaScript
[2015/2016] JavaScript
Ivano Malavolta
 

Similar to Promises - Asynchronous Control Flow (20)

Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
 
Asynchronous development in JavaScript
Asynchronous development  in JavaScriptAsynchronous development  in JavaScript
Asynchronous development in JavaScript
 
Node js
Node jsNode js
Node js
 
Avoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promisesAvoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promises
 
Promises & limbo
Promises & limboPromises & limbo
Promises & limbo
 
Angular promises and http
Angular promises and httpAngular promises and http
Angular promises and http
 
You promise?
You promise?You promise?
You promise?
 
Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)
 
Asynchronous JavaScript Programming with Callbacks & Promises
Asynchronous JavaScript Programming with Callbacks & PromisesAsynchronous JavaScript Programming with Callbacks & Promises
Asynchronous JavaScript Programming with Callbacks & Promises
 
AngularJS, More Than Directives !
AngularJS, More Than Directives !AngularJS, More Than Directives !
AngularJS, More Than Directives !
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
 
Nevyn — Promise, It's Async! Swift Language User Group Lightning Talk 2015-09-24
Nevyn — Promise, It's Async! Swift Language User Group Lightning Talk 2015-09-24Nevyn — Promise, It's Async! Swift Language User Group Lightning Talk 2015-09-24
Nevyn — Promise, It's Async! Swift Language User Group Lightning Talk 2015-09-24
 
Async History - javascript
Async History - javascriptAsync History - javascript
Async History - javascript
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation Javascript
 
JavaScript Interview Questions 2023
JavaScript Interview Questions 2023JavaScript Interview Questions 2023
JavaScript Interview Questions 2023
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
 
Better react/redux apps using redux-saga
Better react/redux apps using redux-sagaBetter react/redux apps using redux-saga
Better react/redux apps using redux-saga
 
[2015/2016] JavaScript
[2015/2016] JavaScript[2015/2016] JavaScript
[2015/2016] JavaScript
 

Recently uploaded

HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
panagenda
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
Jakub Marek
 
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
Edge AI and Vision Alliance
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Precisely
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying AheadDigital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Wask
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
Chart Kalyan
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
Shinana2
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Tatiana Kojar
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
DanBrown980551
 
Azure API Management to expose backend services securely
Azure API Management to expose backend services securelyAzure API Management to expose backend services securely
Azure API Management to expose backend services securely
Dinusha Kumarasiri
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
tolgahangng
 
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
Alex Pruden
 
FREE A4 Cyber Security Awareness Posters-Social Engineering part 3
FREE A4 Cyber Security Awareness  Posters-Social Engineering part 3FREE A4 Cyber Security Awareness  Posters-Social Engineering part 3
FREE A4 Cyber Security Awareness Posters-Social Engineering part 3
Data Hops
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
Hiroshi SHIBATA
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
MichaelKnudsen27
 

Recently uploaded (20)

HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
 
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying AheadDigital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying Ahead
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
 
Azure API Management to expose backend services securely
Azure API Management to expose backend services securelyAzure API Management to expose backend services securely
Azure API Management to expose backend services securely
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
 
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
 
FREE A4 Cyber Security Awareness Posters-Social Engineering part 3
FREE A4 Cyber Security Awareness  Posters-Social Engineering part 3FREE A4 Cyber Security Awareness  Posters-Social Engineering part 3
FREE A4 Cyber Security Awareness Posters-Social Engineering part 3
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
 

Promises - Asynchronous Control Flow

  • 2. A long time ago in a galaxy far far away...
  • 3. The problem Q: How to control the asynchronous flow of your application when there are dependencies between two steps? A: I can use Callbacks :) function asyncFunction1(function (err, result) { // do something here... asyncFuncion2(function (err2, result2) { // other stuff here... }) })
  • 4. However… Callbacks can get ugly module.exports.verifyPassword = function(user, password, done) { if(typeof password !== ‘string’) { done(new Error(‘password should be a string’)) } computeHash(password, user.passwordHashOpts, function(err, hash) { if(err) { done(err) } done(null, hash === user.passwordHash) }) } Callback being called multiple times
  • 5. This one is easily fixed though... module.exports.verifyPassword = function(user, password, done) { if(typeof password !== ‘string’) { return done(new Error(‘password should be a string’)) } computeHash(password, user.passwordHashOpts, function(err, hash) { if(err) { return done(err) } return done(null, hash === user.passwordHash) }) } Always return when calling the callback
  • 6. Q: How execute asynchronous function in parallel and proceed when all have finished? But what about parallel execution? var finished = [false, false] function asyncFunction1(function (err, result) { // do some stuff finished[0] = true if (finished[0] === true && finished[1] === true) { // proceed… } }) function asyncFunction2(function (err, result) { // do some other stuff finished[1] = true if (finished[0] === true && finished[1] === true) { // proceed… } })
  • 8. Find a better way you must...
  • 9. The good ol’ async¹ module async.waterfall([ function(callback) { callback(null, 'one', 'two'); }, function(arg1, arg2, callback) { // arg1 = 'one' and arg2 = 'two' callback(null, 'three'); }, function(arg1, callback) { // arg1 = 'three' callback(null, 'done'); } ], function (err, result) { // result now equals 'done' }); async.parallel([ function(callback){ setTimeout(function(){ callback(null, 'one'); }, 200); }, function(callback){ setTimeout(function(){ callback(null, 'two'); }, 100); } ], // optional callback function(err, results){ // the results array will equal ['one','two'] even though // the second function had a shorter timeout. }); ¹ https://github.com/caolan/async
  • 10. But it can get cumbersome too... What if I need to pass an argument to the first function in the waterfall? async.waterfall([ async.apply(myFirstFunction, 'zero'), mySecondFunction, myLastFunction, ], function (err, result) { // result = 'done' }); function myFirstFunction(arg1, callback) { // arg1 now equals 'zero' callback(null, 'one', 'two'); } function mySecondFunction(arg1, arg2, callback) { // arg1 = 'one' and arg2 = 'two' callback(null, 'three'); } function myLastFunction(arg1, callback) { // arg1 = 'three' callback(null, 'done'); }
  • 11. DRY* Error handling can be tiresome… You have to bubble your errors up in every layer of code you have. And if you forget doing so, a wild bug may appear... * Don’t Repeat Yourserlf async.waterfall([ function(callback) { doSomething(function(err, result){ if (err) return callback(err) callback(null, result, 'another-thing'); }) }, function(arg1, arg2, callback) { doAnotherStuff(function(err, result){ if (err) return callback(err) callback(null, result); }) }, function(arg1, callback) { doAnotherStuff(function(err, result){ if (err) return callback(err) callback(null, result); }) } ], function (err, result) { // result now equals 'done' }); Bug used “confusion”. It was very effective.
  • 13. What is a promise? The core idea behind promises is that it represents the result of an asynchronous operation. A promise is in one of three different states: - Pending: The initial state of a promise. - Fulfilled: The state of a promise representing a successful operation. - Rejected: The state of a promise representing a failed operation.
  • 14. How does a promise work? The State Diagram of a promise is as simple as this one:
  • 15. Clarifying a little bit - When pending, a promise: ○ may transition to either the fulfilled or rejected state. - When fulfilled, a promise: ○ must not transition to any other state. ○ must have a value, which must not change. - When rejected, a promise: ○ must not transition to any other state. ○ must have a reason, which must not change.
  • 16. The “then” method The “then” method is called when a promise is either fulfilled or rejected. This two conditions are treated by different callbacks: promise.then(onFulfilled, onRejected) - onFulfilled(value): value of fulfilment of the promise as its first argument - onRejected(reason): reason of rejection of the promise as its first argument. This argument is optional. functionReturningPromise.then(function(value){ // do something with value }, function (reason) { // do something if failed })
  • 17. Promise chaining The “then” method always returns a new promise, so it can be chained. Even if your callbacks return a value, the promise implementation will wrap it into a brand new promise before returning it. functionReturningPromise.then(function(value){ return 10 }) .then(function (number) { console.log(number) // 10 }) .then(...) .then(...) .then(...) .then(...) .then(...) // The chaining can go indefinetly
  • 18. Error handling If any error is thrown within a then callback, a rejected promise will be automatically returned with the error as its reason. The immediately after then call will only execute the onRejected callback. If onRejected is not provided or is not a function, the error will be passed to the next chained then. If no then call in the chain have a onRejected callback, the error will be thrown to the main code. functionReturningPromise.then(function(value){ throw new Error(‘Something bad happened’) }) .then(function (someArg) { // do nothing }, function (reason) { console.log(reason) // Error: Something … return 42 // Will return a resolved promise })
  • 19. Error bubbling If onRejected is not provided or is not a function, the error will be passed to the next chained then. If the next chained then has the onRejected callback, it will be called, giving you a possibility of dealing with the error. IMPORTANT: if you don’t throw a new error or re-throw the error argument, the then method will return a promise that is resolved with the return value of the onRejected callback. If no then call in the chain have a onRejected callback, the error will be thrown to the main code. functionReturningPromise.then(function(value){ throw new Error(‘Something bad happened’) }) .then(function (number) { console.log(number) // Will be bypassed }) .then(function (someArg) { // do nothing }, function (reason) { console.log(reason) // Error: Something … // Will return a resolved promise }) .then(function (number) { console.log(number) // undefined because the previous // callback doesn’t return a value })
  • 20. Error catching In most situations, you only want to deal with possible errors once. You can do this by adding a then call at the end of your chain with only the onRejected callback. This way, any subsequent then call after the error throwing will be bypassed and the error will only be handled by the last one. Since the last then call is only for error catching, you don’t need to set a onResolved callback and may use null instead. functionReturningPromise.then(function(value){ throw new Error(‘Something bad happened’) }) .then(function (...) { // Will be bypassed }) .then(function (...) { // Will be bypassed }) .then(function (...) { // Will be bypassed }) .then(null, function (error) { // Error: Something … console.log(error) })
  • 22. Standardization Promise A+¹ is a standard specification for promise implementations. It allows interoperability between different promise libraries. You don’t need to worry about what implementation of promise a 3rd party module uses, you can seamlessly integrate it into your code, as long as it respects the A+ specs. The specs are at the same time powerful and dead simple: less than 100 lines of text in plain English. ¹ https://promisesaplus.com/ someLibrary.methodReturningPromise() .then(function (result) { return anotherLibrary.anotherPromise() }) .then(function (anotherResult) { // ... })
  • 23. I mean, a de facto standard... Promises are now part of the core¹ of EcmaScript 6 (ES6). That means it is available as part of the standard library of modern Javascript engines: ● Node.js >= v0.12.* ● Any modern and updated browser (Firefox, Chrome, Safari, Edge, etc. -- NOT IE) ¹ https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise ² http://caniuse.com/#feat=promises ²
  • 25. Parallel execution Most of the promise implementations (including the core one in ES6) have some extra methods will allow you to have asynchronous code running in parallel. The Promise.all¹ method will take an array of promises as an argument and will return a promise that will only be resolved when and if all the input promises are resolved. The Promise.race¹ method will also take an array of promises, but will return a promise that resolves to the value of the first of the input to be resolved. Promise.all([promise1, promise2, promise3]) .then(function (result) { // result will be an array with the values // of the input promises. // The order is preserved, so you’ll have: // [resPromise1, resPromise2, resPromise3] }) Promise.race([promise1, promise2, promise3]) .then(function (result) { // result will be the either resPromise1, // resPromise2 or resPromise3, depending // on which promise finishes firt }) ¹ Not part of the Promise A+ specification
  • 26. The catch method The catch¹ method is just a syntactic sugar around the last-then-treats-error pattern discussed before. functionReturningPromise.then(function(value){ throw new Error(‘Something bad happened’) }) .then(null, function (error) { console.log(error) }) // Can be rewritten as following in most // implementations of Promise: functionReturningPromise.then(function(value){ throw new Error(‘Something bad happened’) }) .catch(function (error) { console.log(error) }) ¹ Not part of the Promise A+ specification
  • 27. Creating settled promises Another syntactic sugar allows you to create promises that are already fulfilled or rejected, through the helper methods Promise.resolve and Promise.reject. This can be very useful in cases that your interface states you should return a promise, but you already have the value to return (ex.: caching). var cache = {} functionReturningPromise.then(function(value){ throw new Error(‘Something bad happened’) }) .then(function (result) { if (cache[result] !== undefined) { return Promise.resolve(cache[result]) } else { return getFreshData(result) .then(function (data) { cache[result] = data return data )} } }) ¹ This is not part of the Promise A+ specification
  • 28. Non-standard¹ cool extras The finally method allows you to have a callback that will be executed either if the promise chain is resolved or rejected. The tap method is a really useful syntactic sugar that allows you to intercept the result of a promise, but automatically passing it down the chain. The props method is like Promise.all, but resolves to an object instead of an array. db.connect() // Implemented using bluebird .then(function() { // run some queries }) .finally(function () { // no matter what, close the connection db.disconnect() }) var Promise = require('bluebird') Promise.resolve(42) // will print 42 into the console and return it .tap(console.log.bind(console)) .then(function (result) { // result is still 42 }) Promise.props({ a: getA(), b : getB()}) .then(function (obj) { // Will print { a : …, b : … } console.log(obj) }) ¹ Based on Bluebird (http://bluebirdjs.com/docs/) -- a full-featured promise implementation
  • 29. Promisify all the things!
  • 30. Converting callback-based code Bluebird¹ has some utility methods that will adapt callback-based functions and libs to use promises. The Promise.promisify method will take any error-first callback and return a promise that will be resolved if the callback is called without error or rejected otherwise. The Promise.promisifyAll method will take an objects and iterate over all it’s methods and create a new implementation of them, keeping the same name, suffixed by “Async”. Var Promise = require('bluebird’) var fs = require('fs') var readFileAsync = Promise.promisify(fs.readFile) readFileAsync('someFile.ext') .then(function (contents) { // do something }) // or... Promise.promisifyAll(fs) fs.readFileAsync('someFile.ext') .then(function (contents) { // do something }) ¹ http://bluebirdjs.com/
  • 32.
  • 33. @hjpbarcelos henriquebarcelos Henrique José Pires Barcelos Fullstack Software Engineer @ Revmob About the author