Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Common Patterns Using Promises
Search
Neal Lindsay
January 07, 2016
Technology
2
2.3k
Common Patterns Using Promises
Neal Lindsay
January 07, 2016
Tweet
Share
More Decks by Neal Lindsay
See All by Neal Lindsay
Higher-Order Promises
neall
1
68
Promises are _Fun_damental
neall
0
61
Other Decks in Technology
See All in Technology
AzureでのIaC - Bicep? Terraform? それ早く言ってよ会議
torumakabe
1
430
あたらしい上流工程の形。 0日導入からはじめるAI駆動PM
kumaiu
5
760
Frontier Agents (Kiro autonomous agent / AWS Security Agent / AWS DevOps Agent) の紹介
msysh
3
150
10Xにおける品質保証活動の全体像と改善 #no_more_wait_for_test
nihonbuson
PRO
2
210
20260204_Midosuji_Tech
takuyay0ne
1
140
コスト削減から「セキュリティと利便性」を担うプラットフォームへ
sansantech
PRO
3
1.4k
Deno・Bunの標準機能やElysiaJSを使ったWebSocketサーバー実装 / ラーメン屋を貸し切ってLT会! IoTLT 2026新年会
you
PRO
0
300
IaaS/SaaS管理における SREの実践 - SRE Kaigi 2026
bbqallstars
4
1.7k
GSIが複数キー対応したことで、俺達はいったい何が嬉しいのか?
smt7174
3
150
GitHub Issue Templates + Coding Agentで簡単みんなでIaC/Easy IaC for Everyone with GitHub Issue Templates + Coding Agent
aeonpeople
1
190
Contract One Engineering Unit 紹介資料
sansan33
PRO
0
13k
顧客との商談議事録をみんなで読んで顧客解像度を上げよう
shibayu36
0
190
Featured
See All Featured
Crafting Experiences
bethany
1
48
The Spectacular Lies of Maps
axbom
PRO
1
520
New Earth Scene 8
popppiees
1
1.5k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2k
Navigating Team Friction
lara
192
16k
Information Architects: The Missing Link in Design Systems
soysaucechin
0
770
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
580
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
359
30k
How STYLIGHT went responsive
nonsquared
100
6k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
1.9k
Unsuck your backbone
ammeep
671
58k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
1.8k
Transcript
Common Patterns Using Promises
Neal Lindsay @neall
[email protected]
what is a promise? patterns anti-patterns stunning conclusion!
a container you get immediately for a value you get
eventually
promises are for asynchronous data
event handlers? streaming data? each “then” only happens once
2010 - promises/A 2011 - jQuery “deferreds” 2012 - promises/A+
2013 - browser promises
new Promise(function(resolve, reject) { if (thingsGoWell) { resolve('value'); } else
{ reject(Error('reason')); } });
Promise.resolve('value'); Promise.reject(Error('reason'));
p.then( function(value){…}, function(reason){…} );
don't call it a callback (it’s been here for years)
data handler error handler
.then() returns a new promise np = p.then(…);
p ≠ np (dumb math joke)
how does this new promise resolve?
1. falls through if no handler
p.then(f) p.then().then(f)
1. falls through if no handler 2. rejected with any
error thrown 3. resolved with a value returned 4. except… if a promise returned, “becomes” that promise
np = p.then(function(value) { return Promise.resolve(3 + value); });
patterns
chaining vs fanning
get('/dog') .then(JSON.parse) .then(function(dog) {…}); chaining
p = get('/dog').then(JSON.parse); p.then(alert); p.then(playFetch); fanning
cache = {}; getUserWithCache = function(id) { return cache[id] =
cache[id] || getUser(id); }; getUserWithCache(3).then(displayName); // later getUserWithCache(3).then(displayAge);
naming
value: plain old noun p.then(function(dog) {…});
p.then( undefined, function(error) {} ); error: error
p.then( undefined, function(error) {…} ); p.catch( function(error) {…} );
p.then( undefined, function(error) {…} ); p['catch']( function(error) {…} );
function that returns a promise: imperative verb phrase guessFavoriteColor() .then(function(color)
{…});
promise: past-tense verb phrase gotScruffy = getDog('scruffy'); gotScruffy .then(function(scruffy) {…});
name handler functions for readability
getDog('scruffy') .then(function(dog) { return getPerson(dog.ownerId); }) .then(function(person) { return person.name;
}) .then(alert);
getOwner = function(obj) { return getPerson(obj.ownerId); }; readName = function(obj)
{ return obj.name; }; getDog('scruffy') .then(getOwner) .then(readName) .then(alert);
use higher- order functions
multiplyBy = function(x) { return function(y) { return x *
y; }; }; timesThree = multiplyBy(3); alert(timesThree(2)); // 6
getOwner = function(obj) { return getPerson(obj.ownerId); }; readName = function(obj)
{ return obj.name; }; getDog('scruffy') .then(getOwner) .then(readName) .then(alert);
readProperty = function(propertyName) { return function(obj) { return obj[propertyName]; };
}; getDog('scruffy') .then(readProperty('ownerId')) .then(getPerson) .then(readProperty('name')) .then(alert);
recover from errors
getDog('scruffy') .then(alert);
var getDefaultDog = function() { return getDog('fluffy'); } getDog('scruffy') .catch(getDefaultDog)
.then(alert);
var getEmergencyDog = function() { return {name: 'claude'}; }; getDog('scruffy')
.catch(getDefaultDog) .catch(getEmergencyDog) .then(alert);
anti-patterns
returning data not in a promise
var getEmergencyDog = function() { return {name: 'claude'}; }; getDog('scruffy')
.catch(getDefaultDog) .catch(getEmergencyDog) .then(alert);
var getEmergencyDog = function() { return Promise.resolve({name: 'claude'}); }; getDog('scruffy')
.catch(getDefaultDog) .catch(getEmergencyDog) .then(alert);
unnecessary function wrapping
get('/dogs') .then(function(response) { return JSON.parse(response); }) .then(doSomething);
get('/dogs') .then(JSON.parse) .then(doSomething);
except…
getDog('scruffy') .then(window.alert); // works getDog('scruffy') .then(console.log); // TypeError!
getDog('scruffy') .then(function(dog) { console.log(dog) }); // works, but meh :-/
getDog('scruffy') .then(console.log.bind(console));
synchronous code after promise code
getDog('scruffy').then(alert); alert('Good dog!');
getDog('scruffy') .then(alert) .then(function() { alert('Good dog!'); });
inappropriately chaining queries
getDog('scruffy') .then(goWalkies);
can you walk my dog too?
getDog('scruffy') .then(goWalkies); getDog('fluffy') .then(goWalkies);
getDog('scruffy') .then(function (scruffy) { return new Promise(function(resolve) { getDog('fluffy') .then(function(fluffy)
{ resolve([scruffy, fluffy]); }); }); }) .then(goWalkies);
Promise .all([ getDog('scruffy'), getDog('fluffy'), getEmergencyDog() ]) .then(goWalkies);
Promise .all([ getDog('scruffy').then(getOwnerForDog), getDog('fluffy').then(getOwnerForDog), getEmergencyDog().then(getOwnerForDog) ]) .then(renegotiateWalkingRates);
conclusion
chain vs fan
naming
move inline functions into named variables
replace named functions with generated functions
return promises even for some static data for consistency
don't wrap functions for no reason
but do use function.bind() when needed
keep synchronous code above promise code
don't chain expensive queries when you can avoid it
thank you
questions?