https://javascript.info/promise-basics
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://dev.to/codeofaccuracy/promises-in-javascript-2e09
A Promise is a special JavaScript object. It produces a value after an asynchronous (aka, async) operation completes successfully, or an error if it does not complete successfully due to time out, network error, and so on.
(OR)
In JavaScript, a Promise is a built-in object that represents the eventual completion (or failure) of an asynchronous operation, and its resulting value. It provides a cleaner and more organized way to handle asynchronous code, avoiding the infamous callback hell.
the promise can be created with the constructor syntax, like this:
let promise = new Promise(function(resolve, reject) {
// Code to execute
});The constructor function takes a function as an argument. This function is called the executor function.
The executor function takes two arguments, resolve and reject.
Its arguments resolve and reject are callbacks provided by JavaScript itself. Our code is only inside the executor.
When the executor obtains the result, be it soon or late, doesn’t matter, it should call one of these callbacks:
resolve(value)— if the job is finished successfully, with resultvalue.reject(error)— if an error has occurred,erroris the error object.
So to summarize: the executor runs automatically and attempts to perform a job. When it is finished with the attempt, it calls resolve if it was successful or reject if there was an error.
The promise object returned by the new Promise constructor has these internal properties:
state— initially"pending", then changes to either"fulfilled"whenresolveis called or"rejected"whenrejectis called.result— initiallyundefined, then changes tovaluewhenresolve(value)is called orerrorwhenreject(error)is called.
The new Promise() constructor returns a promise object. As the executor function needs to handle async operations, the returned promise object should be capable of informing when the execution has been started, completed (resolved) or retuned with error (rejected).
A promise object has the following internal properties:
state– This property can have the following values:
pending: Initially when the executor function starts the execution.fulfilled: When the promise is resolved.rejected: When the promise is rejected.

2. result – This property can have the following values:
undefined: Initially when thestatevalue ispending.value: Whenresolve(value)is called.error: Whenreject(error)is called.- To handle the response from the Promise, you can use the
then()andcatch()methods. Thethen()method is called when the Promise is resolved successfully, and it receives the data as a parameter. Thecatch()method is called when the Promise is rejected with an error, and it receives the error message as a parameter.
Promise.all()
The Promise.all() method allows you to run multiple Promises in parallel and wait for all of them to complete. This method takes an array of Promises as its argument and returns a new Promise that is fulfilled when all of the Promises in the array have been fulfilled.
const promise1 = new Promise((resolve) => setTimeout(resolve, 2000, "foo"));
const promise2 = 10;
const promise3 = new Promise((resolve) =>
setTimeout(resolve, 3000, "bar")
);
Promise.all([promise1, promise2, promise3]).then((values) =>
console.log(values)
);
// Output: ["foo", 10, "bar"]
In the example above, we create three Promises and pass them to the Promise.all() method. The then() method is used to log the array of values returned by the Promises when they are all fulfilled.
Promise.race()
The Promise.race() method allows you to run multiple Promises in parallel and return the value of the first Promise that is fulfilled.
const promise1 = new Promise((resolve) => setTimeout(resolve, 2000, "foo"));
const promise2 = new Promise((resolve) =>
setTimeout(resolve, 3000, "bar")
);
Promise.race([promise1, promise2]).then((value) => console.log(value));
// Output: "foo"
In the example above, we create two Promises and pass them to the Promise.race() method. The then() method is used to log the value of the first Promise that is fulfilled. In this case, promise1 is fulfilled first, so its value ("foo") is logged.
Promise.allSettled()
Promise.allSettled() was introduced in ES2020. It takes an array of Promises as its input and returns a new Promise that resolves to an array of objects, one for each Promise in the input array. Each object in the resulting array represents the state of the corresponding Promise and contains two properties:
status: The status of the Promise. It can be either "fulfilled" or "rejected".
value or reason: Depending on whether the Promise was fulfilled or rejected, this property contains either the fulfilled value or the rejection reason.
Here's an example of how Promise.allSettled() works:
const promises = [
Promise.resolve("resolved"),
Promise.reject("rejected"),
Promise.resolve("resolved again"),
];
Promise.allSettled(promises).then((results) => console.log(results));
// Output: [
// { status: "fulfilled", value: "resolved" },
// { status: "rejected", reason: "rejected" },
// { status: "fulfilled", value: "resolved again" }
// ]
In this example, we create an array of three Promises. The first and third Promises are fulfilled with the values "resolved" and "resolved again", respectively. The second Promise is rejected with the reason "rejected". We then pass this array of Promises to Promise.allSettled(), which returns a new Promise that resolves to an array of three objects representing the state of each Promise. The then() method is used to log the resulting array of objects to the console.
Note that unlike Promise.all(), Promise.allSettled() waits for all Promises to settle (i.e., either fulfill or reject), regardless of their outcome. This means that even if some of the Promises are rejected, the resulting Promise returned by Promise.allSettled() will still resolve with an array of objects representing the state of all the Promises.
Promise concurrency
The Promise class offers four static methods to facilitate async task concurrency:
Promise.all()Fulfills when all of the promises fulfill; rejects when any of the promises rejects.
Promise.allSettled()Fulfills when all promises settle.
The
Promise.allSettled()static method takes an iterable of promises as input and returns a singlePromise. This returned promise fulfills when all of the input's promises settle (including when an empty iterable is passed), with an array of objects that describe the outcome of each promise.Promise.any()Fulfills when any of the promises fulfills; rejects when all of the promises reject.
Promise.race()Settles when any of the promises settles. In other words, fulfills when any of the promises fulfills; rejects when any of the promises rejects.
The
Promise.race()static method takes an iterable of promises as input and returns a singlePromise. This returned promise settles with the eventual state of the first promise that settles.const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value);
// Both resolve, but promise2 is faster
});
// Expected output: "two"
- Promise.all() resolves when all the promises resolve.
- Promise.allSettled() resolves when all the promises settle, i.e., either fulfill or get rejected.
- Promise.any() resolves as soon as any one of the promises resolves.
- Promise.race() resolves as soon as any one of the promises settles, i.e., either fulfills or gets rejected.
- promise.reject(reason) return a new rejected promise with the reason for rejection some as passed.
- promise.resolve(value) return a new resolved promise with the value some as passed.
Promise.all(iterable) This method takes an iterable of promises and resolves to a single promise that resolves when either all the promises in the iterable resolves or any one rejects.
Case I: Resolves when all the promises resolve: In this case, the final resolved value will be an array containing aggregated values from all the promises from the iterable.
Case II: Resolves when any one of the rejects: In this case, the reason for the rejected promise is the reason the first promise got rejected from the iterable.
// Creating 3 promises const firstPromise = 60; const secondPromise = Promise.resolve(25); const thirdPromise = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'Resolved!'); }); Promise.all([firstPromise, secondPromise, thirdPromise]) .then((values) => { console.log(values); }); // expected output: Array [60, 25, "Resolved!"]Promise.allSettled(iterable) This method takes an iterable of promises and returns a new promise only when all the promises get settled, i.e., are in fulfilled or rejected state. This method is mainly used when the promises passed in the iterable are not connected to each other, and we just want to know what they result in.
On the other hand, Promise.all() is used when the promises are interdependent, and we want to stop the execution when any one of them gets rejected.
// Creating 3 promises const firstPromise = 60; const secondPromise = Promise.resolve(25); const thirdPromise = new Promise((resolve, reject) => { setTimeout(reject, 100, 'Rejected'); }); Promise.allSettled([firstPromise, secondPromise, thirdPromise]) .then((results) => results.forEach((result) => console.log(result.status))); // expected output: // "fulfilled" // "fulfilled" // "rejected"- Promise.any(iterable) This method takes an iterable of promises, and as soon as one of the promises gets resolved, it gets resolved with the value of the first resolved promise.
If none of the promises gets resolved, i.e., all of them get rejected, then the promise gets rejected with an aggregated error formed by grouping all the individual errors.
// Creating 3 promises const firstPromise = 60; const secondPromise = Promise.resolve(25); const thirdPromise = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'Resolved!'); }); Promise.any([firstPromise, secondPromise, thirdPromise]) .then((value) => { console.log(value); }); // expected output: 60- Promise.race(iterable) This method takes an iterable of promises and returns a promise that fulfills or rejects as soon as any one of the promises from the iterable gets fulfilled or rejected.
If fulfilled, the final returned promise has the value of the fulfilled promise. If rejected, it picks the reason from the rejected promise.
// Creating 3 promises const firstPromise = new Promise((resolve, reject) => { setTimeout(resolve, 300, 'one'); }); const secondPromise = new Promise((resolve, reject) => { setTimeout(resolve, 200, 'two'); }); Promise.race([firstPromise, secondPromise]).then((value) => { console.log(value); // Both resolve, but secondPromise is faster }); // expected output: "two"- Promise.reject(reason) This method is used to return a new rejected promise with the reason same as the one passed as the parameter.
// Creating 3 promises const resolved = (result) => { console.log('Resolved'); } const rejected = (reason) => { console.error(reason); } Promise.reject(new Error('fail')).then(resolved, rejected); // expected output: Error: fail- Promise.resolve(value) This method returns a resolved promise with the value passed as the parameter. If the value is thenable (i.e., then can be used ), it will follow the then's and then return the final value.
Note: In cases where we do not know if a value is a promise, promise.resolve() it, and it will return the value as a promise.
Asynchronous programming in JavaScript can be a bit challenging, especially when dealing with code that depends on network requests or other long-running tasks. However, the introduction of the
asyncandawaitkeywords inES2017 (also known as ES8)has greatly simplified asynchronous programming in JavaScript. In this article, we'll explore whatasyncandawaitare, and how to use them.What are async and await?
asyncandawaitare two new keywords introduced in ES2017 that simplify asynchronous programming in JavaScript. Theasynckeyword is used to define an asynchronous function, which returns a promise that is resolved with the function's return value.awaitkeyword is used to pause the execution of anasyncfunction until a promise is resolved.
An async function is defined like this:
async function myAsyncFunction() { // Code here }Inside an
asyncfunction, you can use theawaitkeyword to pause the function execution until a promise is resolved. The syntax for using await looks like this:let result = await myPromise;myPromiseis a promise that you want to wait for, and result is the value that the promise resolves to.Fetching data from an API
Let's take a look at an example that demonstrates how to use
asyncandawaitto fetch data from an API.Suppose we have an API endpoint that returns a list of users. The endpoint is available at https://jsonplaceholder.typicode.com/users. We want to fetch this data and log the names of the users to the console.
Here's how we can do it using
asyncandawait:async function getUsers() { try { const response = await fetch('https://jsonplaceholder.typicode.com/users'); const data = await response.json(); const names = data.map(user => user.name); console.log(names); } catch (error) { console.error(error); } } getUsers();Here, we define an
asyncfunction calledgetUsersthat fetches the data from the API using thefetchfunction. We then use theawaitkeyword topausethe function execution until the data is fetched and parsed as JSON using the json method of the response object.Once we have the data as an array of user objects, we use the
mapmethod to extract the name property of each user, and then log the resulting array of names to the console.In case there's an error during the fetch or parsing process, we handle it using a
try-catchblock.Finally, we call the
getUsersfunction to start the asynchronous operation.
Comments
Post a Comment