Asynchronous
mean in JavascriptWhen you have a long-running synchronous code (e.g. generate 10,000,0000 prime numbers), JS code will be stuck until this code completes because JS is single threaded
.
Async
allows a long-running operation to return immediately.
The thread will continue to the rest of the program, then resume when the long-running operation completes (resolves).
Promise
A Promise
represents theĀ future result of an asynchronous operation.
.then()
Handles resolved
or rejected
value of a Promise
.
Takes in two parameters:
fulfilled Promise
and rejected Promise
function api() { return new Promise((resolve, reject) => { // ... }) }
Using .then()
can write asynchronous code in a way that resembles synchronous code which is easier to follow.
const promise1 = new Promise((resolve, reject) => { resolve("Success!"); }); promise1.then((value) => { console.log(value); // "Success!" });
.then
stores the callbacks within the Promise
it is called on and immediately returns another Promise
object, allowing you to chain calls to other Promise
methods.
api() .then(function(result){ return api2(); }) .then(function(result2){ return api3(); }) .then(function(result3){ // do something with result3 }) .catch(function(error) { //handle any error });
catch
is same as a try { ... } catch
block structure.If the return value within .then()
is not a promise, it's implicitly wrapped in a Promise
and then resolved
.
const p2 = new Promise((resolve, reject) => { resolve(1); }); p2.then((value) => { console.log(value); // 1 return value + 1; }).then((value) => { // synchronous value works console.log(value); // 2 }); p2.then((value) => { console.log(value); // 1 });
Promise
vs Callback
Promises are NOT Callbacks
Before Promise, Async JS codes relied on callback functions to be executed after a desired time.
Promise
and callbacks
can be used to achieve the async, they are fundamentally different things.Chaining multiple asynchronous operations after other in a row with callback
resulted 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);
async
Syntactical sugar for Promise
.
// Arrow Function // named arrow function expression const foo = async() => { // ... } // single arg // avoid const foo = async arr => { // do something with arr } // multiple args const foo = async(arr, callback) => { // use arr and callback } // Function Declaration async function foo() { // ... } // anonymous async in callback const foo = event.onCall(async() => { // ... })
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( (res) => // ... ) .catch( (e) => console.error(e) );; }, [])
Async
vs Promise
Main difference is in scope
In the below example, promise is kicked off right as they are defined
// Operation A & Operation B can run in parallel Promise.all([ returnsAPromise(opA), returnsAPromise(opB) ]) .then(res => { // waits info from both Operations A & B console.log("done") } ); // With Async // Operation A executes first, then Operation B const asyncFn = async () => { // Operation A runs first const resultA = await returnsAPromise(opA); // Operation B runs after Operation A completes const resultB = await returnsAPromise(opB); // Then, Operation C,D,E... runs console.log("done"); } asyncFn();
To parallel process async
/await
, we use it with Promise.all()
and combine scope via destructuring:
const asyncFnParallel = async () => { // Operation A & Operation B can run in parallel const [resultA, resultB] = await Promise.all([ returnsAPromise(opA), returnsAPromise(opB) ]); // Operation C,D,E... runs after Operation A and Operation B console.log("done"); } asyncFnParallel();
Promise
vs Async
Promise
s run automatically without being called
You don't "declare" Promises
:
new Promise
creates a Promise
.
Promise
returns.If you want to define a Promise, but don't want to start it until specific point in time, you define it inside async
function:
async function startPromise() { // ...other Promise can sit here too } let processPromise = startPromise();