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
Fluent Conf: Rise of Async JavaScript
Search
Jeremy Fairbank
March 09, 2016
Programming
6
1k
Fluent Conf: Rise of Async JavaScript
Jeremy Fairbank
March 09, 2016
Tweet
Share
More Decks by Jeremy Fairbank
See All by Jeremy Fairbank
Connect.Tech 2020: Advanced Cypress Testing
jfairbank
1
190
CodeMash 2020: Solving the Boolean Identity Crisis
jfairbank
1
140
CodeMash 2020: Practical Functional Programming
jfairbank
1
310
Connect.Tech 2019: Practical Functional Programming
jfairbank
0
340
Connect.Tech 2019: Solving the Boolean Identity Crisis
jfairbank
0
170
Lambda Squared 2019: Solving the Boolean Identity Crisis
jfairbank
0
120
All Things Open 2018: Practical Functional Programming
jfairbank
2
260
Connect.Tech 2018: Effective React Testing
jfairbank
1
150
Fluent Conf 2018: Building web apps with Elm Tutorial
jfairbank
2
830
Other Decks in Programming
See All in Programming
リストビュー画面UX改善の振り返り
splcywolf
0
130
API for docs
soutaro
2
900
MCP調べてみました! / Exploring MCP
uhzz
2
2.2k
Strategic Design (DDD)for the Frontend @DDD Meetup Stuttgart
manfredsteyer
PRO
0
110
Java 24まとめ / Java 24 summary
kishida
3
490
これだけは知っておきたいクラス設計の基礎知識 version 2
masuda220
PRO
24
6.2k
Deoptimization: How YJIT Speeds Up Ruby by Slowing Down / RubyKaigi 2025
k0kubun
0
580
AI Coding Agent Enablement - エージェントを自走させよう
yukukotani
14
5.9k
データベースエンジニアの仕事を楽にする。PgAssistantの紹介
nnaka2992
9
4.5k
「”誤った使い方をすることが困難”な設計」で良いコードの基礎を固めよう / phpcon-odawara-2025
taniguhey
0
120
SEAL - Dive into the sea of search engines - Symfony Live Berlin 2025
alexanderschranz
1
130
Django for Data Science (Boston Python Meetup, March 2025)
wsvincent
0
330
Featured
See All Featured
Music & Morning Musume
bryan
47
6.5k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
21k
Stop Working from a Prison Cell
hatefulcrawdad
268
20k
Rebuilding a faster, lazier Slack
samanthasiow
80
8.9k
4 Signs Your Business is Dying
shpigford
183
22k
Automating Front-end Workflow
addyosmani
1369
200k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
34
2.2k
How GitHub (no longer) Works
holman
314
140k
Why Our Code Smells
bkeepers
PRO
336
57k
The Pragmatic Product Professional
lauravandoore
33
6.5k
Bash Introduction
62gerente
611
210k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
Transcript
the RISEof async… JavaScript Jeremy Fairbank blog.jeremyfairbank.com @elpapapollo | gh/jfairbank
We help brands excel. pushagency.io Your website, SimplyBuilt. simplybuilt.com
None
None
None
None
“Call me maybe?”
Async API Callback
Callback fetchUserById(1, function(err, user) { if (err) { console.error('Could not
retrieve user'); } else { console.log(user); } });
}); }); }); }); }); }); Callback Callback Callback Callback
Callback Callback
function fetchCustomerNameForOrder(orderId, done, fail) { fetchOrder(orderId, function(err, order) { if
(err) { logError(err); fail(err); } else { fetchCustomer( order.customerId, function(err, customer) { if (err) { logError(err); fail(err); } else { done(customer.name); } } ); } }); }
function fetchCustomerNameForOrder(orderId, done, fail) { fetchOrder(orderId, function(err, order) { if
(err) { logError(err); fail(err); } else { fetchCustomer( order.customerId, function(err, customer) { if (err) { logError(err); fail(err); } else { done(customer.name); } } ); } }); }
function fetchCustomerNameForOrder(orderId, done, fail) { fetchOrder(orderId, function(err, order) { if
(err) { logError(err); fail(err); } else { fetchCustomer( order.customerId, function(err, customer) { if (err) { logError(err); fail(err); } else { done(customer.name); } } ); } }); }
Async API ?
Promise function fetchCustomerNameForOrder(orderId) { return fetchOrder(orderId) .then(order => fetchCustomer(order.customerId)) .then(customer
=> customer.name); }
.then(...) .then(...) .then(...) .then(...) .then(...) .then(...) .then(...) .then(...)
Error Error Error Error
function fetchCustomerNameForOrder(orderId) { return fetchOrder(orderId) .then(order => fetchCustomer(order.customerId)) .then(customer =>
customer.name) .catch(err => { logError(err); throw err; }); }
Getting there…
• Readable, synchronous program flow • Nonblocking • Use native
flow control constructs
async function fetchCustomerNameForOrder(orderId) { try { const order = await
fetchOrder(orderId); const customer = await fetchCustomer(order.customerId); return customer.name; } catch (err) { logError(err); throw err; } }
async function fetchCustomerNameForOrder(orderId) { try { const order = await
fetchOrder(orderId); const customer = await fetchCustomer(order.customerId); return customer.name; } catch (err) { logError(err); throw err; } }
async function fetchCustomerNameForOrder(orderId) { try { const order = await
fetchOrder(orderId); const customer = await fetchCustomer(order.customerId); return customer.name; } catch (err) { logError(err); throw err; } }
async function fetchCustomerNameForOrder(orderId) { try { const order = await
fetchOrder(orderId); const customer = await fetchCustomer(order.customerId); return customer.name; } catch (err) { logError(err); throw err; } }
None
Await
function fetchOrder(orderId) { return fetch(`/orders/${orderId}`) .then(response => response.json()); } function
printOrder(orderId) { fetchOrder(orderId) .then(order => console.log(order)); }
function fetchOrder(orderId) { return fetch(`/orders/${orderId}`) .then(response => response.json()); } async
function printOrder(orderId) { const order = await fetchOrder(orderId); console.log(order); }
async printOrder(orderId) { const order = await fetchOrder(orderId); console.log(order); }
fetchOrder(orderId) order
async printOrder(orderId) { const order = await fetchOrder(orderId); console.log(order); }
await
async printOrder(orderId) { const order = await fetchOrder(orderId); console.log(order); }
await order
await order
await order
async printOrder(orderId) { const order = await fetchOrder(orderId); console.log(order); }
?
async function printOrder(orderId) { const order = await fetchOrder(orderId); console.log(order);
} printOrder(1); Invoke
async function printOrder(orderId) { const order = await fetchOrder(orderId); console.log(order);
} printOrder(1); Encounter await
async function printOrder(orderId) { const order = await fetchOrder(orderId); console.log(order);
} printOrder(1); Wrap in Promise.resolve
Wrap in Promise.resolve async function printOrder(orderId) { const promise =
Promise.resolve(fetchOrder(orderId)); console.log(order); } printOrder(1);
async function printOrder(orderId) { const promise = Promise.resolve(fetchOrder(orderId)); console.log(order); }
printOrder(1); Wrap rest with then callback
async function printOrder(orderId) { const promise = Promise.resolve(fetchOrder(orderId)); return promise.then(order
=> { console.log(order); return Promise.resolve(undefined); }); } printOrder(1); Wrap rest with then callback
async function printOrder(orderId) { const promise = Promise.resolve(fetchOrder(orderId)); return promise.then(order
=> { console.log(order); return Promise.resolve(undefined); }); } printOrder(1); Wrap implicit return with Promise.resolve
function fetchCustomerNameForOrder(orderId) { return Promise.resolve(fetchOrder(orderId)) .then(order => { return Promise.resolve(fetchCustomer(order.customerId))
.then(customer => { return Promise.resolve(customer.name); }); }); } ?
async function meaningOfLife() { return 42; } meaningOfLife() === 42;
???
async function meaningOfLife() { return 42; } function meaningOfLife() {
return Promise.resolve(42); } meaningOfLife() .then(answer => answer === 42);
Exceptional Situations
async function printOrder(orderId) { try { const order = await
fetchOrder(orderId); console.log(order); } catch (e) { console.log('Error retrieving order', e); } }
async function printOrder(orderId) { try { const order = await
fetchOrder(orderId); console.log(order); } catch (e) { console.log('Error retrieving order', e); } } ?
function fetchOrder(orderId) { return fetch(`/orders/${orderId}`) .then(resp => { if (resp.status
=== 404) { throw new Error('Order not found'); } return resp.json(); }); }
function fetchOrder(orderId) { return new Promise((resolve, reject) => { $.get(`/orders/${orderId}`)
.done(order => resolve(order)) .fail(resp => { if (resp.status === 404) { reject(new Error('Order not found')); } }); }); }
Error Error Error Error
Regain Control
async function findOrCreateOrder(orderId) { let order; if (await orderExists(orderId)) {
order = await fetchOrder(orderId); } else { order = await createOrder(); } return order; }
async function findOrCreateOrder(orderId) { let order; if (await orderExists(orderId)) {
order = await fetchOrder(orderId); } else { order = await createOrder(); } return order; }
async function printOrders(orderIds) { for (const id of orderIds) {
const order = await fetchOrder(id); console.log(order); } }
async function printOrders(orderIds) { for (const id of orderIds) {
const order = await fetchOrder(id); console.log(order); } }
async function printOrders(orderIds) { for (const id of orderIds) {
const order = await fetchOrder(id); console.log(order); } } Problem?
async function printOrders(orderIds) { for (const id of orderIds) {
const order = await fetchOrder(id); console.log(order); } } printOrders([1, 2, 3]);
printOrders([1, 2, 3]); await fetchOrder(1); await fetchOrder(2); await fetchOrder(3);
printOrders([1, 2, 3]); await fetchOrder(1); await fetchOrder(2); await fetchOrder(3);
printOrders([1, 2, 3]); await fetchOrder(1); await fetchOrder(2); await fetchOrder(3);
async function printOrders(orderIds) { const orders = await Promise.all( orderIds.map(fetchOrder)
); orders.forEach(order => console.log(order)); }
async function printOrders(orderIds) { const orders = await Promise.all( orderIds.map(fetchOrder)
); orders.forEach(order => console.log(order)); }
printOrders([1, 2, 3]); await Promise.all([ fetchOrder(1), fetchOrder(2), fetchOrder(3) ]);
printOrders([1, 2, 3]); Demo rise.of.async.jeremyfairbank.com
None
$ npm install --save-dev \ babel-core \ babel-cli \ babel-preset-es2015
\ babel-plugin-syntax-async-functions \ babel-plugin-transform-regenerator \ babel-plugin-transform-runtime
.babelrc { "presets": ["es2015"], "plugins": [ "syntax-async-functions", "transform-regenerator", "transform-runtime" ]
}
$ node_modules/.bin/babel-node myAsyncFile.js
• tc39.github.io/ecmascript-asyncawait/ • github.com/tc39/ecmascript-asyncawait • github.com/tc39/ecma262 Resources
THANKS! Jeremy Fairbank blog.jeremyfairbank.com @elpapapollo | gh/jfairbank speakerdeck.com/jfairbank/fluent-conf-rise-of-async-javascript SLIDES: github.com/jfairbank/rise-of-async-js-talk
CODE: