- Clone the repository
- Run
npm install
- To run a file,
npx ts-node file-relative-path.ts
I will start this topic with some basic consepts:
- Synchronous operations are done sequentially, one operation must finish before the thread can move to the next. Its a blocking architecture.
- Asynchronous operations can be executed in any order, or even simultaneously. Its a non-blocking architecture.
"The async and await keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains." (Mozilla)
That said, i just discovered recently that i was using blocking code, instead of Asynchronous parallel or concurrent operations.
Lets that a loot at the code bellow:
const operation1 = await serviceOne() //3 seconds
const operation2 = await serviceTwo() //1 second
// sec------1---------2---------3---------4
// =============================O operation1
// =========O operation2
// =======================================O Total Elapsed Time (4 seconds)
This code seems ok, but it has a flaw: if operation2 dont depend on operation1, then youre losing performance, because its a blocking operation. Lets suppose serviceOne() takes 3 seconds to be completed and serviceTwo() takes 1 second. Following this approach, it would take 4 seconds to complete both operations (3+1).
Now, if we run the code bellow, both operations would start their execution almost at the same time, being executed concurrently. After 3 seconds (the longest time), both operations would be completed. The code will still execute operation2 after operation1 but it has already been executed, saving 1 second.
const op1 = serviceOne() //start execution
const op2 = serviceTwo() //start execution
const operation1 = await op1
const operation2 = await op2
// sec------1---------2---------3
// =============================O operation1
// =========O operation2
// =============================O Total Elapsed Time (3 seconds)
You can also achieve the same result with promise.all
const [operation1, operation2] = Promise.all([serviceOne(), serviceTwo()])
Imagine a frontend application making 4 api calls and each one takes 1 second. With the blocking approach, it would take 4 seconds to complete the operations (1+1+1+1), while it would take only 1 second to complete all operations executing concurrently.
Bellow are the code examples with blocking, concurrently and parallel promise execution:
- Raw Code - Async/Await and Promise.All
- Run in TSPlayground
- To run in your computer:
npx ts-node examples\async-await-promise-all.ts