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
66
Promises are _Fun_damental
neall
0
60
Other Decks in Technology
See All in Technology
OpenAI gpt-oss ファインチューニング入門
kmotohas
2
1.2k
Adminaで実現するISMS/SOC2運用の効率化 〜 アカウント管理編 〜
shonansurvivors
4
440
SwiftUIのGeometryReaderとScrollViewを基礎から応用まで学び直す:設計と活用事例
fumiyasac0921
0
160
業務効率化をさらに加速させる、ノーコードツールとStep Functionsのハイブリッド化
smt7174
2
130
Reflections of AI: A Trilogy in Four Parts (GOTO; Copenhagen 2025)
ondfisk
0
110
エンタメとAIのための3Dパラレルワールド構築(GPU UNITE 2025 特別講演)
pfn
PRO
0
120
AWS Top Engineer、浮いてませんか? / As an AWS Top Engineer, Are You Out of Place?
yuj1osm
2
210
BI ツールはもういらない?Amazon RedShift & MCP Server で試みる新しいデータ分析アプローチ
cdataj
0
100
能登半島災害現場エンジニアクロストーク 【JAWS FESTA 2025 in 金沢】
ditccsugii
0
470
リセラー企業のテクサポ担当が考える、生成 AI 時代のトラブルシュート 2025
kazzpapa3
1
150
LLM時代にデータエンジニアの役割はどう変わるか?
ikkimiyazaki
6
1.2k
大規模サーバーレスAPIの堅牢性・信頼性設計 〜AWSのベストプラクティスから始まる現実的制約との向き合い方〜
maimyyym
7
4.2k
Featured
See All Featured
The Cult of Friendly URLs
andyhume
79
6.6k
How GitHub (no longer) Works
holman
315
140k
Producing Creativity
orderedlist
PRO
347
40k
Designing for Performance
lara
610
69k
GraphQLとの向き合い方2022年版
quramy
49
14k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
9
870
BBQ
matthewcrist
89
9.8k
The Cost Of JavaScript in 2023
addyosmani
54
9k
Navigating Team Friction
lara
190
15k
The Language of Interfaces
destraynor
162
25k
Documentation Writing (for coders)
carmenintech
75
5k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.5k
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?