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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Jeremy Fairbank
March 09, 2016
Programming
1.2k
6
Share
Fluent Conf: Rise of Async JavaScript
Jeremy Fairbank
March 09, 2016
More Decks by Jeremy Fairbank
See All by Jeremy Fairbank
Connect.Tech 2020: Advanced Cypress Testing
jfairbank
1
250
CodeMash 2020: Solving the Boolean Identity Crisis
jfairbank
1
190
CodeMash 2020: Practical Functional Programming
jfairbank
1
350
Connect.Tech 2019: Practical Functional Programming
jfairbank
0
410
Connect.Tech 2019: Solving the Boolean Identity Crisis
jfairbank
0
220
Lambda Squared 2019: Solving the Boolean Identity Crisis
jfairbank
0
170
All Things Open 2018: Practical Functional Programming
jfairbank
2
280
Connect.Tech 2018: Effective React Testing
jfairbank
1
200
Fluent Conf 2018: Building web apps with Elm Tutorial
jfairbank
2
920
Other Decks in Programming
See All in Programming
ドメインイベントでビジネスロジックを解きほぐす #phpcon_odawara
kajitack
3
820
JAWS-UG横浜 #100 祝・第100回スペシャルAWS は VPC レスの時代へ
maroon1st
0
190
AIベース静的検査器の偽陽性率を抑える工夫3選
orgachem
PRO
4
370
Claude Code × Gemini × Ebitengine ゲーム制作素人WebエンジニアがGoでゲームを作った話
webzawa
0
170
GitHubCopilotCLIをはじめよう.pdf
htkym
0
290
書籍「ユーザーストーリーマッピング」が私のバイブル
asumikam
4
440
クラウドネイティブなエンジニアに向ける Raycastの魅力と実際の活用事例
nealle
2
230
感情を設計する
ichimichi
5
1.6k
Claude CodeでETLジョブ実行テストを自動化してみた
yoshikikasama
0
1k
Offline should be the norm: building local-first apps with CRDTs & Kotlin Multiplatform
renaudmathieu
0
230
mruby on C#: From VM Implementation to Game Scripting (RubyKaigi 2026)
hadashia
2
810
CursorとClaudeCodeとCodexとOpenCodeを実際に比較してみた
terisuke
1
500
Featured
See All Featured
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
170
Embracing the Ebb and Flow
colly
88
5k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
410
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.5k
Paper Plane (Part 1)
katiecoart
PRO
0
6.9k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.9k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
380
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.6k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
160
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.5k
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: