$30 off During Our Annual Pro Sale. View Details »
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
66
Promises are _Fun_damental
neall
0
61
Other Decks in Technology
See All in Technology
AWS CLIの新しい認証情報設定方法aws loginコマンドの実態
wkm2
6
700
学習データって増やせばいいんですか?
ftakahashi
2
300
Kubernetes Multi-tenancy: Principles and Practices for Large Scale Internal Platforms
hhiroshell
0
120
日本Rubyの会の構造と実行とあと何か / hokurikurk01
takahashim
4
1k
Debugging Edge AI on Zephyr and Lessons Learned
iotengineer22
0
170
評価駆動開発で不確実性を制御する - MLflow 3が支えるエージェント開発
databricksjapan
1
120
ブロックテーマとこれからの WordPress サイト制作 / Toyama WordPress Meetup Vol.81
torounit
0
550
re:Invent 2025 ふりかえり 生成AI版
takaakikakei
1
190
文字列の並び順 / Unicode Collation
tmtms
3
520
生成AI時代の自動E2Eテスト運用とPlaywright実践知_引持力哉
legalontechnologies
PRO
0
220
第4回 「メタデータ通り」 リアル開催
datayokocho
0
120
RAG/Agent開発のアップデートまとめ
taka0709
0
160
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.8k
How to Think Like a Performance Engineer
csswizardry
28
2.4k
Into the Great Unknown - MozCon
thekraken
40
2.2k
Side Projects
sachag
455
43k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
970
Producing Creativity
orderedlist
PRO
348
40k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Bash Introduction
62gerente
615
210k
Leading Effective Engineering Teams in the AI Era
addyosmani
8
1.3k
KATA
mclloyd
PRO
32
15k
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?