SlideShare a Scribd company logo
.then
JAVASCRIPT PROMISE
A Good JavaScript Abstraction Pattern
@josephj6802
WHY
Render multiple dropdowns

with non-duplicate AJAX calls
Need AJAX call?
Any same URL
is processing?
Already has

cached data?
All selected values
are matched …
The reason I decided to investigate Promise…
ASYNC & CALLBACK
Handle result when it’s done in the future
Asynchronous Code
Everywhere in JavaScript
setTimeout(function () {!
// do something !
}, 1000);
require(['lodash', 'jquery'], !
function (_, $) {!
// do something with lodash and jQuery!
}!
);
$('form').on('submit', function (e) {!
// do something when user submit form!
});!
!
$('img').on('load', function (e) {!
// do something when img loaded!
});!
!
$('img').on('error', function (e) {!
// do something when img fails loading!
});
$.ajax('/terms.json', function () {!
// do something after api data !
// being loaded!
})
Delay
RequireJS
AJAX
DOM Events
fs.readFile('foo.txt', function () {!
// do something after foo.txt !
// being loaded!
})
Node.js
Asynchronous Code
Everywhere is Callback
setTimeout(function () {!
// do something !
}, 1000);
require(['lodash', 'jquery'], !
function (_, $) {!
// do something with lodash and jQuery!
}!
);
$('form').on('submit', function () {!
// do something when user submit form!
});!
!
$('img').on('load', function () {!
// do something when img loaded!
});!
!
$('img').on('error', function () {!
// do something when img fails loading!
});
$.ajax('/terms.json', function () {!
// do something after api data !
// being loaded!
})
Delay
RequireJS
AJAX
DOM Events
fs.readFile('foo.txt', function () {!
// do something after foo.txt !
// being loaded!
})
Node.js
Asynchronous Code
Everywhere is Callback
setTimeout(function () {!
// do something !
}, 1000);
require(['lodash', 'jquery'], !
function (_, $) {!
// do something with lodash and jQuery!
}!
);
$('form').on('submit', function () {!
// do something when user submit form!
});!
!
$('img').on('load', function () {!
// do something when img loaded!
});!
!
$('img').on('error', function () {!
// do something when img fails loading!
});
$.ajax('/terms.json', function () {!
// do something after api data !
// being loaded!
})
Delay
RequireJS
AJAX
DOM Events
fs.readFile('foo.txt', function () {!
// do something after foo.txt !
// being loaded!
})
Node.js
Nothing wrong with Callback
Use it when your scenario is simple
Sequencial Requests
function GitHubber() {}!
!
GitHubber.prototype.getUserRepos = function (name, callback) {!
!
// Authorisation pass?!
var url = '/api/authorize';

makeRequest(url, function (data, success) {!
// (Omit) Callback if it fails… !
// Get user ID by name!
url = '/api/getUserInfo/' + name + '?token=' + data.token;!
makeRequest(url, function (data, success) {!
// (Omit) Callback if it fails… !
// Get user's repo by user ID!
url = '/api/getUserRepos?token=…&uid=' + data.uid;!
makeRequest(url, function (data, success) {!
// (Omit) Callback if it fails… !
// Finally success

callback(data, true);

});!
});!
});!
};
API Authorisation
Get User ID
Get User Repos
Token
Token + User ID
Callback Hell
GitHubber#getUserRepos
Question: How will you refactor it?
function GitHubber(name) {!
this.name = name;!
this.token = null;!
this.id = null;!
this.repos = [];!
this.steps = ['_authorise', '_getUserInfo', '_getUserRepos'];!
}!
!
var proto = {!
_authorise: function () {!
var url = '/api/authorise';!
makeRequest(url, function (data, success) {!
this.token = data.token;!
this.emit('success', [‘_authorise']);!
});!
},!
_getUserInfo: function () {!
var url = '/api/getUserInfo/' + this.name + 

'?token=' + data.token;!
makeRequest(url, function (data, success) {!
this.id = data.id;!
this.emit('success', [‘_getUserInfo']);!
});!
},!
_getUserRepos: function () {!
var url = '/api/getRepos/?uid=' + this.id + !
'?token=' + data.token;!
makeRequest(url, function (data, success) {!
this.repos = data.repos;!
this.emit('success', [‘_getUserRepos', this.repos]);!
});!
},!
getUserRepos: function (callback) {!
var that = this;!
that.on('success', function (e, method) {!
var offset = that.steps.indexOf(method);!
if (offset !== that.steps.length - 1) { // Other steps!
that[that.steps[offset + 1]];!
} else { // _getUserRepos!
callback(that.repos); !
}!
});!
that[that.steps[0]]();!
}!
};
My Solution
Before understanding Promise
• Break callbacks into
methods with semantic
naming
• Exchange data with
instance variables
• Make use of custom events
I am a big fan of Custom Events
Wolfy87/EventEmitter
function GitHubber(name) {!
this.name = name;!
this.token = null;!
this.id = null;!
this.repos = [];!
this.steps = ['_authorise', '_getUserInfo', '_getUserRepos'];!
}!
!
var proto = {!
_authorise: function () {!
var url = '/api/authorise';!
makeRequest(url, function (data, success) {!
this.token = data.token;!
this.emit('success', [‘_authorise']);!
});!
},!
_getUserInfo: function () {!
var url = '/api/getUserInfo/' + this.name + 

'?token=' + data.token;!
makeRequest(url, function (data, success) {!
this.id = data.id;!
this.emit('success', [‘_getUserInfo']);!
});!
},!
_getUserRepos: function () {!
var url = '/api/getRepos/?uid=' + this.id + !
'?token=' + data.token;!
makeRequest(url, function (data, success) {!
this.repos = data.repos;!
this.emit('success', [‘_getUserRepos', this.repos]);!
});!
},!
getUserRepos: function (callback) {!
var that = this;!
that.on('success', function (e, method) {!
var offset = that.steps.indexOf(method);!
if (offset !== that.steps.length - 1) { // Other steps!
that[that.steps[offset + 1]];!
} else { // _getUserRepos!
callback(that.repos); !
}!
});!
that[that.steps[0]]();!
}!
};
My Solution
Before understanding Promise
• Break callbacks into
methods with semantic
naming
• Exchange data with
instance variables
• Make use of custom events
I am a big fan of Custom Events
Wolfy87/EventEmitter
Better but still not straightforward
Need read carefully to understand the trick
ex. sequence, error handling, and parallel events
JavaScript Promise
Developer’s Wonderland
PROMISE
• A Programming Pattern
• Specialise on Asynchronous Code
• Better Maintainability
• Easier for Scaling
NOT another JavaScript framework
Create A Promise
.then Returns promise immediately
getUserRepos: function () {
!
!
!
},
“Our workers will do
all tasks for you”
“Keep the ticket for now.
I promise you will get 

a fulfilled or rejected result”
• Pending
• Fulfilled: that.repoDeferred.resolve(data.repos)
• Rejected: that.repoDeferred.reject(‘service unavailable’)
that.repoDeferred = new $.Deferred();
that.asyncTasks()
return that.repoDeferred.promise();
“This task may take a while”
Use Promise
.then
gitHubber.getUserRepos()


!
Chain-able fulfilled callback
Rejected callback
Promise is still callback
• .then(fnFulfilled, fnRejected)
• .done(fnFulfilled)
• .fail(fnRejected)
.then(function (repos) {})
.catch(function (msg) {});
Batch Promise
.then
var deferreds = [
gitHubber.getUserRepos(),
gitHubber.getUserProfile(),
gitHubber.getOrgaizations()
];
!
$.when(deferreds)
.done(fnFulfilled)
.fail(fnRejected);
All succeeds
Execute multiple promises together
One or more fails
Promises Array
1st Refactoring
Not attractive… :(
function GitHubber(name) {!
this.name = name;!
this.repos = [];!
this.deferreds = {};!
}!
!
var proto = {!
_authorise: function () {!
var that = this,!
url = '/api/authorise';!
!
that.deferreds._authorise = $.Deferreds();!
$.ajax(url, function (data) {!
that.deferreds._authorise.resolve(data);!
});!
return that.deferreds._authorise.promise();!
},!
_getUserInfo: function () {!
var that = this,!
url = '/api/getUserInfo/' + this.name + '?token=' + data.token;!
!
that.deferreds._getUserInfo = $.Deferreds();!
$.ajax(url, function (data) {!
that.deferreds._getUserInfo.resolve(data.id);!
});!
return that.deferreds._getUserInfo.promise();!
},!
_getUserRepos: function () {!
var that = this,!
url = '/api/getRepos/?uid=' + this.id + '?token=' + data.token;!
!
that.deferreds._getUserRepos = $.Deferreds();!
$.ajax(url, function (data) {!
that.deferreds._getUserRepos.resolve(data.repos);!
});!
function GitHubber (name) {!
this.name = name;!
this.token = null;!
that.repos = [];!
}!
!
var proto = {!
getUserRepos: function (callback) {!
var that = this,!
deferred = $.Deferred();!
!
if (that.repos.length) {!
deferred.resolve(that.repos);!
return;!
}!
!
$.ajax('/api/authorise')!
.then(function (data) {!
that.token = data.token;!
return $.ajax('/api/getUserInfo/' + that.name +'?token=' + data.token);!
})!
.then(function (data) {!
return $.ajax('/api/getRepos/?uid=' + data.uid + '?token=' + that.token);!
})!
.then(function (data) {!
that.repos = data.repos;!
deferred.resolve(data.repos);!
});!
!
return deferred.promise();!
}!
};
2nd: jQuery Promises
$.ajax
$.when
$.getJSON
$.ajax() is also a promise object!
function GitHubber (name) {!
this.name = name;!
this.token = null;!
that.repos = [];!
}!
!
var proto = {!
getUserRepos: function (callback) {!
var that = this,!
deferred = $.Deferred();!
!
if (that.repos.length) {!
deferred.resolve(that.repos);!
return;!
}!
!
$.ajax('/api/authorise')!
.then(function (data) {!
that.token = data.token;!
return $.ajax('/api/getUserInfo/' + that.name +'?token=' + data.token);!
})!
.then(function (data) {!
return $.ajax('/api/getRepos/?uid=' + data.uid + '?token=' + that.token);!
})!
.then(function (data) {!
that.repos = data.repos;!
deferred.resolve(data.repos);!
});!
!
return deferred.promise();!
}!
};
2nd: jQuery Promises
$.ajax
$.when
$.getJSON
$.ajax() is also a promise object!
You can reduce huge amount of code
by chaining & wrapping promise object properly
Promise v.s. Callback
Why Promise?
var promise = $.ajax(url);!
promise.done(callback);
$.ajax(url, callback)
Promise Callback
• Portability - async task must be fulfilled or rejected in delegated methods.
• Consistency - .resolve(), .reject() , .then(), .done(), .catch(), rejected, fulfilled, pending
• Chaining - .then() makes sequential tasks easier to execute
• Straightforward - .then() makes our code easier to read
“First-class API for asynchronous tasks”
Scalability
UserSession.signIn()
.then(this._promisePurchase(video))
Using JavaScript Promises to Reason About
User Interaction
Abstracted Session Checking, Login Popup, Validation,
Video Purchasing and Watching Video with Promise!
With Promise…
.then
• We defines sequence in a very straightforward
way (.then)
• Built-in error handling API (.fail)
• Batch execute parallel tasks easily (Promise.all)
Solved a lot of async design issues
PROMISE IN THE WILD
Environments and Libraries for Promise
Standard Spec: Promises/A+
Promise in Browsers
All Modern browsers support Promise
except IE 11 and all its earlier versions
Promise & jQuery
jQuery’s Deferreds aren't Promise/A+ compliant. 

Please avoid to use if you want to use Promise extensively.
$.Deferred
$.when
Promise in Node.js
Node.js added native promise
in stable version 0.12
… comes with memory leak
Libraries
For both Browser and Node.js
• Q.js 

A tool for creating and composing asynchronous promises in JavaScript
• RSVP.js

A lightweight library that provides tools for organising asynchronous code
• when.js

A solid, fast Promises/A+ and when() implementation, plus other async goodies.
• bluebird (most popular)

Bluebird is a full featured promise library with unmatched performance.
Libraries
For both Browser and Node.js
• Q.js 

A tool for creating and composing asynchronous promises in JavaScript
• RSVP.js

A lightweight library that provides tools for organising asynchronous code
• when.js

A solid, fast Promises/A+ and when() implementation, plus other async goodies.
• bluebird (most popular)

Bluebird is a full featured promise library with unmatched performance.
Currently you probably need library for polyfills
Use jQuery Deferred with awareness
Q & A
• Promise - A Programming Pattern
• Specialise on Asynchronous Code
• Better Maintainability
• Easier for Scaling
“First-class API for asynchronous tasks”
Thank You!

More Related Content

What's hot (20)

PDF
Asynchronous programming done right - Node.js
Piotr Pelczar
 
PDF
$q and Promises in AngularJS
a_sharif
 
PDF
Understanding Asynchronous JavaScript
jnewmanux
 
PPTX
Avoiding Callback Hell with Async.js
cacois
 
PDF
Javascript Promises/Q Library
async_io
 
PDF
Web Crawling with NodeJS
Sylvain Zimmer
 
PDF
Getting Comfortable with JS Promises
Asa Kusuma
 
PDF
Boom! Promises/A+ Was Born
Domenic Denicola
 
PDF
JavaScript Promises
Derek Willian Stavis
 
PDF
History of jQuery
jeresig
 
PPTX
Async Frontiers
Domenic Denicola
 
PPTX
ES6 is Nigh
Domenic Denicola
 
PDF
Callbacks and control flow in Node js
Thomas Roch
 
PDF
Why Redux-Observable?
Anna Su
 
PPTX
Java Script Promise
Alok Guha
 
PDF
ES6: The Awesome Parts
Domenic Denicola
 
PDF
JavaScript promise
eslam_me
 
PDF
Avoiding callback hell with promises
TorontoNodeJS
 
PDF
The Beauty Of Java Script V5a
rajivmordani
 
PDF
Containers & Dependency in Ember.js
Matthew Beale
 
Asynchronous programming done right - Node.js
Piotr Pelczar
 
$q and Promises in AngularJS
a_sharif
 
Understanding Asynchronous JavaScript
jnewmanux
 
Avoiding Callback Hell with Async.js
cacois
 
Javascript Promises/Q Library
async_io
 
Web Crawling with NodeJS
Sylvain Zimmer
 
Getting Comfortable with JS Promises
Asa Kusuma
 
Boom! Promises/A+ Was Born
Domenic Denicola
 
JavaScript Promises
Derek Willian Stavis
 
History of jQuery
jeresig
 
Async Frontiers
Domenic Denicola
 
ES6 is Nigh
Domenic Denicola
 
Callbacks and control flow in Node js
Thomas Roch
 
Why Redux-Observable?
Anna Su
 
Java Script Promise
Alok Guha
 
ES6: The Awesome Parts
Domenic Denicola
 
JavaScript promise
eslam_me
 
Avoiding callback hell with promises
TorontoNodeJS
 
The Beauty Of Java Script V5a
rajivmordani
 
Containers & Dependency in Ember.js
Matthew Beale
 

Viewers also liked (6)

PDF
Promises, Promises: Mastering Async I/O in Javascript with the Promise Pattern
Christian Lilley
 
PDF
The Evolution of Async-Programming (SD 2.0, JavaScript)
jeffz
 
PPTX
Promises Javascript
Julien CROUZET
 
PDF
The Future starts with a Promise
Alexandru Nedelcu
 
PDF
JavaScript Promises
우영 주
 
PDF
The Top Skills That Can Get You Hired in 2017
LinkedIn
 
Promises, Promises: Mastering Async I/O in Javascript with the Promise Pattern
Christian Lilley
 
The Evolution of Async-Programming (SD 2.0, JavaScript)
jeffz
 
Promises Javascript
Julien CROUZET
 
The Future starts with a Promise
Alexandru Nedelcu
 
JavaScript Promises
우영 주
 
The Top Skills That Can Get You Hired in 2017
LinkedIn
 

Similar to JavaScript Promise (20)

PPTX
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Domenic Denicola
 
PPT
You promise?
IT Weekend
 
PDF
Sane Async Patterns
TrevorBurnham
 
PDF
Testing web APIs
FDConf
 
ODP
Node js
hazzaz
 
PDF
Douglas Crockford: Serversideness
WebExpo
 
PDF
How to actually use promises - Jakob Mattsson, FishBrain
Codemotion Tel Aviv
 
PPTX
Call stack, event loop and async programming
Masters Academy
 
PPTX
asyncjavascript.pptxdgdsgdffgfdgfgfgfdgfdgf
zmulani8
 
PDF
Event driven javascript
Francesca1980
 
PDF
Event driven javascript
Francesca1980
 
PDF
The evolution of java script asynchronous calls
Huy Hoàng Phạm
 
PPTX
Promises, promises, and then observables
Stefan Charsley
 
PPTX
Async & Parallel in JavaScript
Eyal Vardi
 
PPTX
Async discussion 9_29_15
Cheryl Yaeger
 
PDF
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
Islam Sharabash
 
PDF
I'm Postal for Promises in Angular
Christian Lilley
 
PPTX
Understanding Async/Await in Javascript
Hao Luo
 
PDF
Intro to Asynchronous Javascript
Garrett Welson
 
PDF
Meet.js promises
Krzysztof Kula
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Domenic Denicola
 
You promise?
IT Weekend
 
Sane Async Patterns
TrevorBurnham
 
Testing web APIs
FDConf
 
Node js
hazzaz
 
Douglas Crockford: Serversideness
WebExpo
 
How to actually use promises - Jakob Mattsson, FishBrain
Codemotion Tel Aviv
 
Call stack, event loop and async programming
Masters Academy
 
asyncjavascript.pptxdgdsgdffgfdgfgfgfdgfdgf
zmulani8
 
Event driven javascript
Francesca1980
 
Event driven javascript
Francesca1980
 
The evolution of java script asynchronous calls
Huy Hoàng Phạm
 
Promises, promises, and then observables
Stefan Charsley
 
Async & Parallel in JavaScript
Eyal Vardi
 
Async discussion 9_29_15
Cheryl Yaeger
 
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
Islam Sharabash
 
I'm Postal for Promises in Angular
Christian Lilley
 
Understanding Async/Await in Javascript
Hao Luo
 
Intro to Asynchronous Javascript
Garrett Welson
 
Meet.js promises
Krzysztof Kula
 

More from Joseph Chiang (20)

PDF
不断归零的前端人生 - 2016 中国软件开发者大会
Joseph Chiang
 
PDF
Let's Redux!
Joseph Chiang
 
PDF
Automatic Functional Testing with Selenium and SauceLabs
Joseph Chiang
 
PDF
From Hacker to Programmer (w/ Webpack, Babel and React)
Joseph Chiang
 
PDF
F2E for Enterprise
Joseph Chiang
 
PDF
JavaScript Code Quality
Joseph Chiang
 
PDF
F2E, the Keystone
Joseph Chiang
 
PDF
前端的未來 - 前端工程實務訓練
Joseph Chiang
 
PDF
Performance 入門 - 前端工程開發實務訓練
Joseph Chiang
 
PDF
Debugging - 前端工程開發實務訓練
Joseph Chiang
 
PDF
Javascript 入門 - 前端工程開發實務訓練
Joseph Chiang
 
PDF
Node.js 入門 - 前端工程開發實務訓練
Joseph Chiang
 
PDF
前端工程開發實務訓練
Joseph Chiang
 
PDF
YUI 教學 - 前端工程開發實務訓練
Joseph Chiang
 
PDF
CSS 入門 - 前端工程開發實務訓練
Joseph Chiang
 
PDF
HTML 入門 - 前端工程開發實務訓練
Joseph Chiang
 
PDF
模块加载策略 - 2012 SDCC, 北京
Joseph Chiang
 
PDF
YUI is Sexy (for JSDC.tw)
Joseph Chiang
 
PDF
YUI is Sexy - 使用 YUI 作為開發基礎
Joseph Chiang
 
KEY
Git - The Social Coding System
Joseph Chiang
 
不断归零的前端人生 - 2016 中国软件开发者大会
Joseph Chiang
 
Let's Redux!
Joseph Chiang
 
Automatic Functional Testing with Selenium and SauceLabs
Joseph Chiang
 
From Hacker to Programmer (w/ Webpack, Babel and React)
Joseph Chiang
 
F2E for Enterprise
Joseph Chiang
 
JavaScript Code Quality
Joseph Chiang
 
F2E, the Keystone
Joseph Chiang
 
前端的未來 - 前端工程實務訓練
Joseph Chiang
 
Performance 入門 - 前端工程開發實務訓練
Joseph Chiang
 
Debugging - 前端工程開發實務訓練
Joseph Chiang
 
Javascript 入門 - 前端工程開發實務訓練
Joseph Chiang
 
Node.js 入門 - 前端工程開發實務訓練
Joseph Chiang
 
前端工程開發實務訓練
Joseph Chiang
 
YUI 教學 - 前端工程開發實務訓練
Joseph Chiang
 
CSS 入門 - 前端工程開發實務訓練
Joseph Chiang
 
HTML 入門 - 前端工程開發實務訓練
Joseph Chiang
 
模块加载策略 - 2012 SDCC, 北京
Joseph Chiang
 
YUI is Sexy (for JSDC.tw)
Joseph Chiang
 
YUI is Sexy - 使用 YUI 作為開發基礎
Joseph Chiang
 
Git - The Social Coding System
Joseph Chiang
 

Recently uploaded (20)

PDF
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
PPTX
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PDF
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
PPTX
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
PDF
LOOPS in C Programming Language - Technology
RishabhDwivedi43
 
PDF
“NPU IP Hardware Shaped Through Software and Use-case Analysis,” a Presentati...
Edge AI and Vision Alliance
 
PDF
July Patch Tuesday
Ivanti
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PDF
Staying Human in a Machine- Accelerated World
Catalin Jora
 
PPTX
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
PDF
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
PDF
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PDF
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
PDF
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
LOOPS in C Programming Language - Technology
RishabhDwivedi43
 
“NPU IP Hardware Shaped Through Software and Use-case Analysis,” a Presentati...
Edge AI and Vision Alliance
 
July Patch Tuesday
Ivanti
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
Staying Human in a Machine- Accelerated World
Catalin Jora
 
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
Smart Trailers 2025 Update with History and Overview
Paul Menig
 

JavaScript Promise

  • 1. .then JAVASCRIPT PROMISE A Good JavaScript Abstraction Pattern @josephj6802
  • 2. WHY Render multiple dropdowns
 with non-duplicate AJAX calls Need AJAX call? Any same URL is processing? Already has
 cached data? All selected values are matched … The reason I decided to investigate Promise…
  • 3. ASYNC & CALLBACK Handle result when it’s done in the future
  • 4. Asynchronous Code Everywhere in JavaScript setTimeout(function () {! // do something ! }, 1000); require(['lodash', 'jquery'], ! function (_, $) {! // do something with lodash and jQuery! }! ); $('form').on('submit', function (e) {! // do something when user submit form! });! ! $('img').on('load', function (e) {! // do something when img loaded! });! ! $('img').on('error', function (e) {! // do something when img fails loading! }); $.ajax('/terms.json', function () {! // do something after api data ! // being loaded! }) Delay RequireJS AJAX DOM Events fs.readFile('foo.txt', function () {! // do something after foo.txt ! // being loaded! }) Node.js
  • 5. Asynchronous Code Everywhere is Callback setTimeout(function () {! // do something ! }, 1000); require(['lodash', 'jquery'], ! function (_, $) {! // do something with lodash and jQuery! }! ); $('form').on('submit', function () {! // do something when user submit form! });! ! $('img').on('load', function () {! // do something when img loaded! });! ! $('img').on('error', function () {! // do something when img fails loading! }); $.ajax('/terms.json', function () {! // do something after api data ! // being loaded! }) Delay RequireJS AJAX DOM Events fs.readFile('foo.txt', function () {! // do something after foo.txt ! // being loaded! }) Node.js
  • 6. Asynchronous Code Everywhere is Callback setTimeout(function () {! // do something ! }, 1000); require(['lodash', 'jquery'], ! function (_, $) {! // do something with lodash and jQuery! }! ); $('form').on('submit', function () {! // do something when user submit form! });! ! $('img').on('load', function () {! // do something when img loaded! });! ! $('img').on('error', function () {! // do something when img fails loading! }); $.ajax('/terms.json', function () {! // do something after api data ! // being loaded! }) Delay RequireJS AJAX DOM Events fs.readFile('foo.txt', function () {! // do something after foo.txt ! // being loaded! }) Node.js Nothing wrong with Callback Use it when your scenario is simple
  • 7. Sequencial Requests function GitHubber() {}! ! GitHubber.prototype.getUserRepos = function (name, callback) {! ! // Authorisation pass?! var url = '/api/authorize';
 makeRequest(url, function (data, success) {! // (Omit) Callback if it fails… ! // Get user ID by name! url = '/api/getUserInfo/' + name + '?token=' + data.token;! makeRequest(url, function (data, success) {! // (Omit) Callback if it fails… ! // Get user's repo by user ID! url = '/api/getUserRepos?token=…&uid=' + data.uid;! makeRequest(url, function (data, success) {! // (Omit) Callback if it fails… ! // Finally success
 callback(data, true);
 });! });! });! }; API Authorisation Get User ID Get User Repos Token Token + User ID Callback Hell GitHubber#getUserRepos Question: How will you refactor it?
  • 8. function GitHubber(name) {! this.name = name;! this.token = null;! this.id = null;! this.repos = [];! this.steps = ['_authorise', '_getUserInfo', '_getUserRepos'];! }! ! var proto = {! _authorise: function () {! var url = '/api/authorise';! makeRequest(url, function (data, success) {! this.token = data.token;! this.emit('success', [‘_authorise']);! });! },! _getUserInfo: function () {! var url = '/api/getUserInfo/' + this.name + 
 '?token=' + data.token;! makeRequest(url, function (data, success) {! this.id = data.id;! this.emit('success', [‘_getUserInfo']);! });! },! _getUserRepos: function () {! var url = '/api/getRepos/?uid=' + this.id + ! '?token=' + data.token;! makeRequest(url, function (data, success) {! this.repos = data.repos;! this.emit('success', [‘_getUserRepos', this.repos]);! });! },! getUserRepos: function (callback) {! var that = this;! that.on('success', function (e, method) {! var offset = that.steps.indexOf(method);! if (offset !== that.steps.length - 1) { // Other steps! that[that.steps[offset + 1]];! } else { // _getUserRepos! callback(that.repos); ! }! });! that[that.steps[0]]();! }! }; My Solution Before understanding Promise • Break callbacks into methods with semantic naming • Exchange data with instance variables • Make use of custom events I am a big fan of Custom Events Wolfy87/EventEmitter
  • 9. function GitHubber(name) {! this.name = name;! this.token = null;! this.id = null;! this.repos = [];! this.steps = ['_authorise', '_getUserInfo', '_getUserRepos'];! }! ! var proto = {! _authorise: function () {! var url = '/api/authorise';! makeRequest(url, function (data, success) {! this.token = data.token;! this.emit('success', [‘_authorise']);! });! },! _getUserInfo: function () {! var url = '/api/getUserInfo/' + this.name + 
 '?token=' + data.token;! makeRequest(url, function (data, success) {! this.id = data.id;! this.emit('success', [‘_getUserInfo']);! });! },! _getUserRepos: function () {! var url = '/api/getRepos/?uid=' + this.id + ! '?token=' + data.token;! makeRequest(url, function (data, success) {! this.repos = data.repos;! this.emit('success', [‘_getUserRepos', this.repos]);! });! },! getUserRepos: function (callback) {! var that = this;! that.on('success', function (e, method) {! var offset = that.steps.indexOf(method);! if (offset !== that.steps.length - 1) { // Other steps! that[that.steps[offset + 1]];! } else { // _getUserRepos! callback(that.repos); ! }! });! that[that.steps[0]]();! }! }; My Solution Before understanding Promise • Break callbacks into methods with semantic naming • Exchange data with instance variables • Make use of custom events I am a big fan of Custom Events Wolfy87/EventEmitter Better but still not straightforward Need read carefully to understand the trick ex. sequence, error handling, and parallel events
  • 11. PROMISE • A Programming Pattern • Specialise on Asynchronous Code • Better Maintainability • Easier for Scaling NOT another JavaScript framework
  • 12. Create A Promise .then Returns promise immediately getUserRepos: function () { ! ! ! }, “Our workers will do all tasks for you” “Keep the ticket for now. I promise you will get 
 a fulfilled or rejected result” • Pending • Fulfilled: that.repoDeferred.resolve(data.repos) • Rejected: that.repoDeferred.reject(‘service unavailable’) that.repoDeferred = new $.Deferred(); that.asyncTasks() return that.repoDeferred.promise(); “This task may take a while”
  • 13. Use Promise .then gitHubber.getUserRepos() 
 ! Chain-able fulfilled callback Rejected callback Promise is still callback • .then(fnFulfilled, fnRejected) • .done(fnFulfilled) • .fail(fnRejected) .then(function (repos) {}) .catch(function (msg) {});
  • 14. Batch Promise .then var deferreds = [ gitHubber.getUserRepos(), gitHubber.getUserProfile(), gitHubber.getOrgaizations() ]; ! $.when(deferreds) .done(fnFulfilled) .fail(fnRejected); All succeeds Execute multiple promises together One or more fails Promises Array
  • 15. 1st Refactoring Not attractive… :( function GitHubber(name) {! this.name = name;! this.repos = [];! this.deferreds = {};! }! ! var proto = {! _authorise: function () {! var that = this,! url = '/api/authorise';! ! that.deferreds._authorise = $.Deferreds();! $.ajax(url, function (data) {! that.deferreds._authorise.resolve(data);! });! return that.deferreds._authorise.promise();! },! _getUserInfo: function () {! var that = this,! url = '/api/getUserInfo/' + this.name + '?token=' + data.token;! ! that.deferreds._getUserInfo = $.Deferreds();! $.ajax(url, function (data) {! that.deferreds._getUserInfo.resolve(data.id);! });! return that.deferreds._getUserInfo.promise();! },! _getUserRepos: function () {! var that = this,! url = '/api/getRepos/?uid=' + this.id + '?token=' + data.token;! ! that.deferreds._getUserRepos = $.Deferreds();! $.ajax(url, function (data) {! that.deferreds._getUserRepos.resolve(data.repos);! });!
  • 16. function GitHubber (name) {! this.name = name;! this.token = null;! that.repos = [];! }! ! var proto = {! getUserRepos: function (callback) {! var that = this,! deferred = $.Deferred();! ! if (that.repos.length) {! deferred.resolve(that.repos);! return;! }! ! $.ajax('/api/authorise')! .then(function (data) {! that.token = data.token;! return $.ajax('/api/getUserInfo/' + that.name +'?token=' + data.token);! })! .then(function (data) {! return $.ajax('/api/getRepos/?uid=' + data.uid + '?token=' + that.token);! })! .then(function (data) {! that.repos = data.repos;! deferred.resolve(data.repos);! });! ! return deferred.promise();! }! }; 2nd: jQuery Promises $.ajax $.when $.getJSON $.ajax() is also a promise object!
  • 17. function GitHubber (name) {! this.name = name;! this.token = null;! that.repos = [];! }! ! var proto = {! getUserRepos: function (callback) {! var that = this,! deferred = $.Deferred();! ! if (that.repos.length) {! deferred.resolve(that.repos);! return;! }! ! $.ajax('/api/authorise')! .then(function (data) {! that.token = data.token;! return $.ajax('/api/getUserInfo/' + that.name +'?token=' + data.token);! })! .then(function (data) {! return $.ajax('/api/getRepos/?uid=' + data.uid + '?token=' + that.token);! })! .then(function (data) {! that.repos = data.repos;! deferred.resolve(data.repos);! });! ! return deferred.promise();! }! }; 2nd: jQuery Promises $.ajax $.when $.getJSON $.ajax() is also a promise object! You can reduce huge amount of code by chaining & wrapping promise object properly
  • 18. Promise v.s. Callback Why Promise? var promise = $.ajax(url);! promise.done(callback); $.ajax(url, callback) Promise Callback • Portability - async task must be fulfilled or rejected in delegated methods. • Consistency - .resolve(), .reject() , .then(), .done(), .catch(), rejected, fulfilled, pending • Chaining - .then() makes sequential tasks easier to execute • Straightforward - .then() makes our code easier to read “First-class API for asynchronous tasks”
  • 19. Scalability UserSession.signIn() .then(this._promisePurchase(video)) Using JavaScript Promises to Reason About User Interaction Abstracted Session Checking, Login Popup, Validation, Video Purchasing and Watching Video with Promise!
  • 20. With Promise… .then • We defines sequence in a very straightforward way (.then) • Built-in error handling API (.fail) • Batch execute parallel tasks easily (Promise.all) Solved a lot of async design issues
  • 21. PROMISE IN THE WILD Environments and Libraries for Promise Standard Spec: Promises/A+
  • 22. Promise in Browsers All Modern browsers support Promise except IE 11 and all its earlier versions
  • 23. Promise & jQuery jQuery’s Deferreds aren't Promise/A+ compliant. 
 Please avoid to use if you want to use Promise extensively. $.Deferred $.when
  • 24. Promise in Node.js Node.js added native promise in stable version 0.12 … comes with memory leak
  • 25. Libraries For both Browser and Node.js • Q.js 
 A tool for creating and composing asynchronous promises in JavaScript • RSVP.js
 A lightweight library that provides tools for organising asynchronous code • when.js
 A solid, fast Promises/A+ and when() implementation, plus other async goodies. • bluebird (most popular)
 Bluebird is a full featured promise library with unmatched performance.
  • 26. Libraries For both Browser and Node.js • Q.js 
 A tool for creating and composing asynchronous promises in JavaScript • RSVP.js
 A lightweight library that provides tools for organising asynchronous code • when.js
 A solid, fast Promises/A+ and when() implementation, plus other async goodies. • bluebird (most popular)
 Bluebird is a full featured promise library with unmatched performance. Currently you probably need library for polyfills Use jQuery Deferred with awareness
  • 27. Q & A • Promise - A Programming Pattern • Specialise on Asynchronous Code • Better Maintainability • Easier for Scaling “First-class API for asynchronous tasks”