When you have a long running synchornous code (e.g. generate 100000000 prime numbers), your JS code will be stuck until this code completes
Async allows a long running operation to return immediately, continue the rest of the program, then notify when the long running operation completes
Check event-loop page.
A Promise
represents the future result of an asynchronous operation
You can write asynchronous code in a way that resembles synchronous code and is much more easy to follow:
function api() { return new Promise((resolve, reject) => { ... }) } api().then(function(result){ return api2(); }).then(function(result2){ return api3(); }).then(function(result3){ // do work }).catch(function(error) { //handle any error });
Same as a try { ... } catch
block
Promise
vs Callback
Promises are NOT Callbacks
Async JS code executes Callback functions to be executed after the desired time
Async
/Await
async/await
is a syntactic sugar forPromise
// example async function fetchMovies() { const response = await fetch('/movies'); // waits until the request completes... console.log(response); } // example of useEffect in React useEffect(() => { const fetchData = async () => { // some code like fetch() }; await fetchData() .then(...) .catch(console.error);; }, [])
Async
vs Promise
Main difference is in scope
In the below example, promise is kicked off right as they are defined
// With Promise // Operation A & Operation B can run in parallel Promise.all([returnsAPromise(opA), returnsAPromise(opB)]) .then(res => { // waits info from Operations A & B console.log("done") }); // With Async // Operation A executes first, then Operation B const asyncFn = async () => { // Operation A runs const resultA = await returnsAPromise(opA); // Operation B runs after Operation A completes const resultB = await returnsAPromise(opB); // Then, Operation C runs console.log("done"); } asyncFn();
To parallel process async/await, we combine the scopes through destructuring
const asyncFnParallel = async () => { // Operation A & Operation B can run in parallel const [resultA, resultB] = await Promise.all([returnsAPromise(opA), returnsAPromise(opB)]); // Operation C runs after Operation A and Operation B console.log("done"); } asyncFnParallel();
Promises
Chaining two or more asynchronous operations two execute after other in a row with callback results in the pyramid of doom
doSomething(function (result) { doSomethingElse(result, function (newResult) { doThirdThing(newResult, function (finalResult) { console.log(`Got the final result: ${finalResult}`); }, failureCallback); }, failureCallback); }, failureCallback);
With promise, you break out of the pyramid shape
const promise1 = doSomething(); const promise2 = promise1.then(successCallback, failureCallback);
Promise
vs Async
When using promises, they run automatically without being called
You don't "declare" promises
new Promise
creates a promise
If you want to define a Promise, but don't want to start it until specific point in time, put it in an async
function
async function startPromise() { // ...other Promise can sit here too } let processPromise = startPromise();