SlideShare a Scribd company logo
From Node.js to Design Patterns
Luciano Mammino
@loige
👋 Hello, I am Luciano
Cloud & Full stack software engineer
nodejsdesignpatterns.com
Let’s connect:
🌎 loige.co
🐦 @loige
🧳 lucianomammino
👇 Get the slides (and click around…)
loige.link/devcast
@loige
What is Node.js
Node.js is an open-source, cross-platform,
JavaScript runtime environment that executes
JavaScript code outside a web browser.
@loige
Node.js + JavaScript: when?
● Building for the web
○ Websites, APIs, Servers, Single Page Applications, Bots, etc…
● Command-line applications and tools
● Mobile applications (React Native, Ionic, NativeScript, etc.)
● Desktop apps (Electron)
● Embedded & IoT (Espruino, Johnny-Five)
@loige
Async I/O
In JavaScript and in Node.js, input/output operations (e.g. making an HTTP
request) are non-blocking.
@loige
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://google.com")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
System.out.println("Request completed");
A blocking HTTP request (Java)
Output
blocking...
blocking...
<google home page HTML code>
Request completed
Code executed
“In order”
@loige
Is blocking I/O bad?
It depends…
If your application is I/O heavy, then you might have a problem...
@loige
Let’s make 3 requests...
Req 1
Req 2
Req 3
time
@loige
You can always use threads...
Req 1
Req 2
Req 3
time
But threads are…
Complicated
Expensive
A lot of idle time per thread!
wait...
wait...
wait...
@loige
client.get('https://google.com',
(err, resp) => {
console.log(resp.body)
}
)
console.log('Request completed (?)')
👍
With Node.js async I/O
Output
Request “in the
background”
Request completed (?)
<google home page HTML code>
⚠ Code executed
“OUT of order”
Not really completed!
Non-blocking:
execution continues
Callback function
1
2
3
@loige
Mental model
You “just” schedule async I/O and you will get notified when the
operation is completed!
● Async I/O happens in the background asynchronously
● You don’t have to manage threads to get concurrency!
@loige
Let’s do 3 requests with Async I/O
“User” thread
Event loop
(libuv)
time
idle... idle... idle...
Simpler code for the user
Idle time only in one thread
Sched. req1
Sched. req2
Sched. req3 req1 result req3 result req2 result
@loige
I am oversimplifying a bit… 😛
Watch loige.link/event-loop-what-the-heck
if you want to go more in depth!
@loige
Many ways to handle
async flows
@loige
Delete last reservation if confirmed
● Get a guest object from a guest id (async)
● Get the last reservation from the guest object
● Get the details of that reservation (async)
● Delete that reservation if “confirmed” (async)
@loige
Callbacks
function deleteLastReservationIfConfirmed (client, guestId, cb) {
client.getGuest(guestId, (err, guest) => {
if (err) { return cb(err) }
const lastReservation = guest.reservations.pop()
if (typeof lastReservation === 'undefined') {
return cb(null, false)
}
client.getReservation(lastReservation, (err, reservation) => {
if (err) { return cb(err) }
if (reservation.status === 'confirmed') {
client.deleteReservation(reservation.id, (err) => {
if (err) { return cb(err) }
return cb(null, true)
})
}
})
})
}
@loige
Promises
function deleteLastReservationIfConfirmed (client, guestId) {
return client.getGuest(guestId)
.then((guest) => {
const lastReservation = guest.reservations.pop()
if (typeof lastReservation !== 'undefined') {
return client.getReservation(lastReservation)
}
})
.then((reservation) => {
if (!reservation || reservation.status !== 'confirmed') {
return false
}
return client.deleteReservation(reservation.id)
})
}
@loige
Async/Await
async function deleteLastReservationIfConfirmed (client, guestId) {
const guest = await client.getGuest(guestId)
const lastReservation = guest.reservations.pop()
if (typeof lastReservation === 'undefined') {
return false
}
const reservation = await client.getReservation(lastReservation)
if (!reservation || reservation.status !== 'confirmed') {
return false
}
return client.deleteReservation(reservation.id)
}
@loige
Advantages of Async/Await
● Easier to read and reason about (“sequential flow”)
● Easier to deal with conditional async operations
● Unified error handling
(you can catch both synchronous and asynchronous errors)
⚠ To fully understand async/await, you still need to understand callbacks and
promises, don’t ignore them!
@loige
Other ways to handle async
● Events
● Streams
● Async iterators/generators
@loige
Some interesting
async patterns
@loige
const guestIds = ['Peach', 'Toad', 'Mario', 'Luigi']
for (const guestId of guestIds) {
await deleteLastReservationIfConfirmed(client, guestId)
}
Sequential execution
@loige
const guestIds = ['Peach', 'Toad', 'Mario', 'Luigi']
guestIds.forEach(async (guestId) => {
await deleteLastReservationIfConfirmed(client, guestId)
})
Sequential execution ⚠ Common pitfall
Don’t use Array.map or Array.forEach!
forEach will run all the functions without awaiting them, so all the delete
invocations will happen concurrently!
@loige
const guestIds = ['Peach', 'Toad', 'Mario', 'Luigi']
await Promise.all(
guestIds.map(
guestId => deleteLastReservationIfConfirmed(client, guestId)
)
)
Concurrent execution
⚠ Promise.all rejects as soon as one promise rejects. A failure will result in the failure of the entire operation.
@loige
const guestIds = ['Peach', 'Toad', 'Mario', 'Luigi']
const results = await Promise.allSettled(
guestIds.map(
guestId => deleteLastReservationIfConfirmed(client, guestId)
)
)
Concurrent execution - Alternative
[
{ status: 'fulfilled', value: true },
{ status: 'fulfilled', value: true },
{ status: 'rejected', reason: Error },
{ status: 'fulfilled', value: true }
]
@loige
const mapLimit = require('async/mapLimit')
const guestIds = ['Peach', 'Toad', 'Mario', 'Luigi', '...']
const results = await mapLimit(
guestIds,
2, // max concurrency
async (guestId) => deleteLastReservationIfConfirmed(client, guestId)
)
Concurrent execution - limited
When you have a lot of tasks to run and what to keep limited concurrency
Uses the third-party async module (npm.im/async)
@loige
Request batching
Classic flow - one user
HTTP
Server DB
/availability/v1/units
@loige
Request batching
Classic flow - multiple users (no batching)
HTTP
Server DB
/availability/v1/units
/availability/v1/units
/availability/v1/units
@loige
Request batching
Classic flow - multiple users (with batching!)
HTTP
Server DB
/availability/v1/units
/availability/v1/units
/availability/v1/units
📘 Requests in-flight
pending
fulfilled
⏱ /availability/v1/units
⏱
@loige
const { createServer } = require('http')
const server = createServer(async (req, res) => {
const url = new URL(req.url, 'http://localhost')
if (url.pathname !== '/availability/v1/units') {
res.writeHead(404, 'Not found')
return res.end()
}
const units = await getAvailableUnitsFromDb()
res.writeHead(200)
res.end(JSON.stringify(units))
})
server.listen(8000)
The web server
@loige
let pendingRequest = null
async function getAvailableUnitsFromDb () {
if (pendingRequest) {
console.log('batching')
return pendingRequest
}
console.log('Getting data from db')
pendingRequest = db.query('SELECT * FROM units WHERE "availability" > 0')
pendingRequest.finally(() => {
pendingRequest = null
})
return pendingRequest
}
Get units from DB
@loige
Performance comparison
Without batching With batching
+15%
throughput
@loige
In conclusion
● Node.js is a great runtime for I/O bound applications
● It’s also great for full stack web development
● The async model allows you to express concurrent computation effectively
● You still need to master callbacks, promises and async / await!
● There are many patterns that can help you out to keep your code organised
and more performant.
@loige
Want to learn more?
● nodejsdesignpatterns.com - possibly a great book :)
● loige.link/javascript-mdn - mozilla guides
● eloquentjavascript.net - free e-book
● freecodecamp.org - interactive code training
● nodejs.org/api - Node.js official docs
@loige
Thank you!
loige.link/devcast
@loige

More Related Content

PPTX
JavaScript on the Desktop
PPTX
The jsdom
PDF
Build Your Own WebAssembly Compiler
PDF
자바스크립트 비동기 코드(Javascript asyncronous code)
PDF
Converting your JS library to a jQuery plugin
PDF
Pablo Magaz | ECMAScript 2018 y más allá | Codemotion Madrid 2018
PDF
Writing browser extensions_in_kotlin
PDF
Arc of developer part2
JavaScript on the Desktop
The jsdom
Build Your Own WebAssembly Compiler
자바스크립트 비동기 코드(Javascript asyncronous code)
Converting your JS library to a jQuery plugin
Pablo Magaz | ECMAScript 2018 y más allá | Codemotion Madrid 2018
Writing browser extensions_in_kotlin
Arc of developer part2

What's hot (20)

PDF
Workshop 12: AngularJS Parte I
PDF
JavaScript and the AST
PDF
ES2015 workflows
PDF
Decoupling the Ulabox.com monolith. From CRUD to DDD
PDF
Websockets talk at Rubyconf Uruguay 2010
PDF
Callbacks, promises, generators - asynchronous javascript
PDF
dSS API by example
PPTX
Optimizing a large angular application (ng conf)
PDF
_Function Builders in Swift #love_swift
PDF
Async js - Nemetschek Presentaion @ HackBulgaria
PPTX
Node.js for PHP developers
PDF
The evolution of java script asynchronous calls
PDF
Blockchain Coding Dojo - BlockchainHub Graz
PDF
PyconIE 2016 - Kajiki, the fast and validated template engine your were looki...
ODP
Javascript
PPTX
Correcting Common .NET Async/Await Mistakes
PDF
ng-conf 2017: Angular Mischief Maker Slides
PPTX
Correcting Common Async/Await Mistakes in .NET
PPTX
Java with a Clojure mindset
PDF
Introducing perf budgets on CI with puppeteer - perf.now()
Workshop 12: AngularJS Parte I
JavaScript and the AST
ES2015 workflows
Decoupling the Ulabox.com monolith. From CRUD to DDD
Websockets talk at Rubyconf Uruguay 2010
Callbacks, promises, generators - asynchronous javascript
dSS API by example
Optimizing a large angular application (ng conf)
_Function Builders in Swift #love_swift
Async js - Nemetschek Presentaion @ HackBulgaria
Node.js for PHP developers
The evolution of java script asynchronous calls
Blockchain Coding Dojo - BlockchainHub Graz
PyconIE 2016 - Kajiki, the fast and validated template engine your were looki...
Javascript
Correcting Common .NET Async/Await Mistakes
ng-conf 2017: Angular Mischief Maker Slides
Correcting Common Async/Await Mistakes in .NET
Java with a Clojure mindset
Introducing perf budgets on CI with puppeteer - perf.now()
Ad

Similar to From Node.js to Design Patterns (20)

PDF
An opinionated intro to Node.js - devrupt hospitality hackathon
PDF
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
PDF
From Node.js to Design Patterns - BuildPiper
PDF
JavaScript Promises
PPTX
Por que Criamos uma Ferramenta de Load Testing utilizando Playwright e AWS Ba...
KEY
Playing With Fire - An Introduction to Node.js
PDF
Javascript: repetita iuvant
KEY
Writing robust Node.js applications
PPTX
Writing JavaScript for C# Blazor.pptx
PDF
Side effects-con-redux
PDF
soft-shake.ch - Hands on Node.js
PDF
Intro to Asynchronous Javascript
PPTX
asyncjavascript.pptxdgdsgdffgfdgfgfgfdgfdgf
ODP
CompletableFuture
PPTX
Avoiding callback hell in Node js using promises
PPTX
The State of JavaScript (2015)
KEY
Psgi Plack Sfpm
KEY
Psgi Plack Sfpm
PDF
Server Side Swift: Vapor
PPTX
Async Redux Actions With RxJS - React Rally 2016
An opinionated intro to Node.js - devrupt hospitality hackathon
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
From Node.js to Design Patterns - BuildPiper
JavaScript Promises
Por que Criamos uma Ferramenta de Load Testing utilizando Playwright e AWS Ba...
Playing With Fire - An Introduction to Node.js
Javascript: repetita iuvant
Writing robust Node.js applications
Writing JavaScript for C# Blazor.pptx
Side effects-con-redux
soft-shake.ch - Hands on Node.js
Intro to Asynchronous Javascript
asyncjavascript.pptxdgdsgdffgfdgfgfgfdgfdgf
CompletableFuture
Avoiding callback hell in Node js using promises
The State of JavaScript (2015)
Psgi Plack Sfpm
Psgi Plack Sfpm
Server Side Swift: Vapor
Async Redux Actions With RxJS - React Rally 2016
Ad

More from Luciano Mammino (20)

PDF
Serverless Rust: Your Low-Risk Entry Point to Rust in Production (and the ben...
PDF
Did you know JavaScript has iterators? DublinJS
PDF
What I learned by solving 50 Advent of Code challenges in Rust - RustNation U...
PDF
Building an invite-only microsite with Next.js & Airtable - ReactJS Milano
PDF
Let's build a 0-cost invite-only website with Next.js and Airtable!
PDF
Everything I know about S3 pre-signed URLs
PDF
Serverless for High Performance Computing
PDF
Serverless for High Performance Computing
PDF
JavaScript Iteration Protocols - Workshop NodeConf EU 2022
PDF
Building an invite-only microsite with Next.js & Airtable
PDF
Let's take the monolith to the cloud 🚀
PDF
A look inside the European Covid Green Certificate - Rust Dublin
PDF
Monoliths to the cloud!
PDF
The senior dev
PDF
Node.js: scalability tips - Azure Dev Community Vijayawada
PDF
A look inside the European Covid Green Certificate (Codemotion 2021)
PDF
AWS Observability Made Simple
PDF
Semplificare l'observability per progetti Serverless
PDF
Finding a lost song with Node.js and async iterators - NodeConf Remote 2021
PDF
Finding a lost song with Node.js and async iterators - EnterJS 2021
Serverless Rust: Your Low-Risk Entry Point to Rust in Production (and the ben...
Did you know JavaScript has iterators? DublinJS
What I learned by solving 50 Advent of Code challenges in Rust - RustNation U...
Building an invite-only microsite with Next.js & Airtable - ReactJS Milano
Let's build a 0-cost invite-only website with Next.js and Airtable!
Everything I know about S3 pre-signed URLs
Serverless for High Performance Computing
Serverless for High Performance Computing
JavaScript Iteration Protocols - Workshop NodeConf EU 2022
Building an invite-only microsite with Next.js & Airtable
Let's take the monolith to the cloud 🚀
A look inside the European Covid Green Certificate - Rust Dublin
Monoliths to the cloud!
The senior dev
Node.js: scalability tips - Azure Dev Community Vijayawada
A look inside the European Covid Green Certificate (Codemotion 2021)
AWS Observability Made Simple
Semplificare l'observability per progetti Serverless
Finding a lost song with Node.js and async iterators - NodeConf Remote 2021
Finding a lost song with Node.js and async iterators - EnterJS 2021

Recently uploaded (20)

PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
KodekX | Application Modernization Development
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
cuic standard and advanced reporting.pdf
PDF
Empathic Computing: Creating Shared Understanding
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PPTX
Big Data Technologies - Introduction.pptx
PPTX
Cloud computing and distributed systems.
PPTX
sap open course for s4hana steps from ECC to s4
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
MYSQL Presentation for SQL database connectivity
Unlocking AI with Model Context Protocol (MCP)
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
NewMind AI Weekly Chronicles - August'25 Week I
Encapsulation_ Review paper, used for researhc scholars
KodekX | Application Modernization Development
Review of recent advances in non-invasive hemoglobin estimation
cuic standard and advanced reporting.pdf
Empathic Computing: Creating Shared Understanding
Chapter 3 Spatial Domain Image Processing.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Advanced methodologies resolving dimensionality complications for autism neur...
MIND Revenue Release Quarter 2 2025 Press Release
Big Data Technologies - Introduction.pptx
Cloud computing and distributed systems.
sap open course for s4hana steps from ECC to s4
The Rise and Fall of 3GPP – Time for a Sabbatical?
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
MYSQL Presentation for SQL database connectivity

From Node.js to Design Patterns

  • 1. From Node.js to Design Patterns Luciano Mammino @loige
  • 2. 👋 Hello, I am Luciano Cloud & Full stack software engineer nodejsdesignpatterns.com Let’s connect: 🌎 loige.co 🐦 @loige 🧳 lucianomammino
  • 3. 👇 Get the slides (and click around…) loige.link/devcast @loige
  • 4. What is Node.js Node.js is an open-source, cross-platform, JavaScript runtime environment that executes JavaScript code outside a web browser. @loige
  • 5. Node.js + JavaScript: when? ● Building for the web ○ Websites, APIs, Servers, Single Page Applications, Bots, etc… ● Command-line applications and tools ● Mobile applications (React Native, Ionic, NativeScript, etc.) ● Desktop apps (Electron) ● Embedded & IoT (Espruino, Johnny-Five) @loige
  • 6. Async I/O In JavaScript and in Node.js, input/output operations (e.g. making an HTTP request) are non-blocking. @loige
  • 7. OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://google.com") .build(); Response response = client.newCall(request).execute(); System.out.println(response.body().string()); System.out.println("Request completed"); A blocking HTTP request (Java) Output blocking... blocking... <google home page HTML code> Request completed Code executed “In order” @loige
  • 8. Is blocking I/O bad? It depends… If your application is I/O heavy, then you might have a problem... @loige
  • 9. Let’s make 3 requests... Req 1 Req 2 Req 3 time @loige
  • 10. You can always use threads... Req 1 Req 2 Req 3 time But threads are… Complicated Expensive A lot of idle time per thread! wait... wait... wait... @loige
  • 11. client.get('https://google.com', (err, resp) => { console.log(resp.body) } ) console.log('Request completed (?)') 👍 With Node.js async I/O Output Request “in the background” Request completed (?) <google home page HTML code> ⚠ Code executed “OUT of order” Not really completed! Non-blocking: execution continues Callback function 1 2 3 @loige
  • 12. Mental model You “just” schedule async I/O and you will get notified when the operation is completed! ● Async I/O happens in the background asynchronously ● You don’t have to manage threads to get concurrency! @loige
  • 13. Let’s do 3 requests with Async I/O “User” thread Event loop (libuv) time idle... idle... idle... Simpler code for the user Idle time only in one thread Sched. req1 Sched. req2 Sched. req3 req1 result req3 result req2 result @loige
  • 14. I am oversimplifying a bit… 😛 Watch loige.link/event-loop-what-the-heck if you want to go more in depth! @loige
  • 15. Many ways to handle async flows @loige
  • 16. Delete last reservation if confirmed ● Get a guest object from a guest id (async) ● Get the last reservation from the guest object ● Get the details of that reservation (async) ● Delete that reservation if “confirmed” (async) @loige
  • 17. Callbacks function deleteLastReservationIfConfirmed (client, guestId, cb) { client.getGuest(guestId, (err, guest) => { if (err) { return cb(err) } const lastReservation = guest.reservations.pop() if (typeof lastReservation === 'undefined') { return cb(null, false) } client.getReservation(lastReservation, (err, reservation) => { if (err) { return cb(err) } if (reservation.status === 'confirmed') { client.deleteReservation(reservation.id, (err) => { if (err) { return cb(err) } return cb(null, true) }) } }) }) } @loige
  • 18. Promises function deleteLastReservationIfConfirmed (client, guestId) { return client.getGuest(guestId) .then((guest) => { const lastReservation = guest.reservations.pop() if (typeof lastReservation !== 'undefined') { return client.getReservation(lastReservation) } }) .then((reservation) => { if (!reservation || reservation.status !== 'confirmed') { return false } return client.deleteReservation(reservation.id) }) } @loige
  • 19. Async/Await async function deleteLastReservationIfConfirmed (client, guestId) { const guest = await client.getGuest(guestId) const lastReservation = guest.reservations.pop() if (typeof lastReservation === 'undefined') { return false } const reservation = await client.getReservation(lastReservation) if (!reservation || reservation.status !== 'confirmed') { return false } return client.deleteReservation(reservation.id) } @loige
  • 20. Advantages of Async/Await ● Easier to read and reason about (“sequential flow”) ● Easier to deal with conditional async operations ● Unified error handling (you can catch both synchronous and asynchronous errors) ⚠ To fully understand async/await, you still need to understand callbacks and promises, don’t ignore them! @loige
  • 21. Other ways to handle async ● Events ● Streams ● Async iterators/generators @loige
  • 23. const guestIds = ['Peach', 'Toad', 'Mario', 'Luigi'] for (const guestId of guestIds) { await deleteLastReservationIfConfirmed(client, guestId) } Sequential execution @loige
  • 24. const guestIds = ['Peach', 'Toad', 'Mario', 'Luigi'] guestIds.forEach(async (guestId) => { await deleteLastReservationIfConfirmed(client, guestId) }) Sequential execution ⚠ Common pitfall Don’t use Array.map or Array.forEach! forEach will run all the functions without awaiting them, so all the delete invocations will happen concurrently! @loige
  • 25. const guestIds = ['Peach', 'Toad', 'Mario', 'Luigi'] await Promise.all( guestIds.map( guestId => deleteLastReservationIfConfirmed(client, guestId) ) ) Concurrent execution ⚠ Promise.all rejects as soon as one promise rejects. A failure will result in the failure of the entire operation. @loige
  • 26. const guestIds = ['Peach', 'Toad', 'Mario', 'Luigi'] const results = await Promise.allSettled( guestIds.map( guestId => deleteLastReservationIfConfirmed(client, guestId) ) ) Concurrent execution - Alternative [ { status: 'fulfilled', value: true }, { status: 'fulfilled', value: true }, { status: 'rejected', reason: Error }, { status: 'fulfilled', value: true } ] @loige
  • 27. const mapLimit = require('async/mapLimit') const guestIds = ['Peach', 'Toad', 'Mario', 'Luigi', '...'] const results = await mapLimit( guestIds, 2, // max concurrency async (guestId) => deleteLastReservationIfConfirmed(client, guestId) ) Concurrent execution - limited When you have a lot of tasks to run and what to keep limited concurrency Uses the third-party async module (npm.im/async) @loige
  • 28. Request batching Classic flow - one user HTTP Server DB /availability/v1/units @loige
  • 29. Request batching Classic flow - multiple users (no batching) HTTP Server DB /availability/v1/units /availability/v1/units /availability/v1/units @loige
  • 30. Request batching Classic flow - multiple users (with batching!) HTTP Server DB /availability/v1/units /availability/v1/units /availability/v1/units 📘 Requests in-flight pending fulfilled ⏱ /availability/v1/units ⏱ @loige
  • 31. const { createServer } = require('http') const server = createServer(async (req, res) => { const url = new URL(req.url, 'http://localhost') if (url.pathname !== '/availability/v1/units') { res.writeHead(404, 'Not found') return res.end() } const units = await getAvailableUnitsFromDb() res.writeHead(200) res.end(JSON.stringify(units)) }) server.listen(8000) The web server @loige
  • 32. let pendingRequest = null async function getAvailableUnitsFromDb () { if (pendingRequest) { console.log('batching') return pendingRequest } console.log('Getting data from db') pendingRequest = db.query('SELECT * FROM units WHERE "availability" > 0') pendingRequest.finally(() => { pendingRequest = null }) return pendingRequest } Get units from DB @loige
  • 33. Performance comparison Without batching With batching +15% throughput @loige
  • 34. In conclusion ● Node.js is a great runtime for I/O bound applications ● It’s also great for full stack web development ● The async model allows you to express concurrent computation effectively ● You still need to master callbacks, promises and async / await! ● There are many patterns that can help you out to keep your code organised and more performant. @loige
  • 35. Want to learn more? ● nodejsdesignpatterns.com - possibly a great book :) ● loige.link/javascript-mdn - mozilla guides ● eloquentjavascript.net - free e-book ● freecodecamp.org - interactive code training ● nodejs.org/api - Node.js official docs @loige