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
330
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
140
Fluent Conf 2018: Building web apps with Elm Tutorial
jfairbank
2
820
Other Decks in Programming
See All in Programming
Gunma.web #55
tinykitten
0
130
ニックトレイン登壇資料
ryotakurokawa
0
120
RubyKaigiで手に入れた HHKB Studioのための HIDRawドライバ
iberianpig
0
160
Identifying and Analyzing Fake OSS with Malware - fukuoka.go#21
rhykw
0
490
보일러플레이트 코드가 진짜 나쁜 건가요?
gaeun5744
0
360
PsySHから紐解くREPLの仕組み
muno92
PRO
1
420
RCPと宣言型ポリシーについてのお話し
kokitamura
2
130
DenoでOpenTelemetryに入門する
yotahada3
2
280
バックエンドNode.js × フロントエンドDeno で開発して得られた知見
ayame113
4
1.2k
PHPer's Guide to Daemon Crafting Taming and Summoning
uzulla
2
620
PHPでお金を扱う時、終わりのない 謎の1円調査の旅にでなくて済む方法
nakka
3
940
いまさら聞けない生成AI入門: 「生成AIを高速キャッチアップ」
soh9834
10
3k
Featured
See All Featured
Understanding Cognitive Biases in Performance Measurement
bluesmoon
27
1.6k
KATA
mclloyd
29
14k
Large-scale JavaScript Application Architecture
addyosmani
511
110k
Typedesign – Prime Four
hannesfritz
41
2.6k
Bash Introduction
62gerente
611
210k
GraphQLの誤解/rethinking-graphql
sonatard
69
10k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
30k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.4k
Code Reviewing Like a Champion
maltzj
521
39k
How to train your dragon (web standard)
notwaldorf
91
5.9k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
4
450
Side Projects
sachag
452
42k
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: