Javascript — Promises

Eishta Mittal
4 min readOct 27, 2022

What is a Promise ?

The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.

In other words,

A Promise is a special JavaScript object. It produces a value after an asynchronous operation completes successfully, or an error if it does not complete successfully.

The word ‘asynchronous’ means that something happens in the future, not right now.

Promise Constructor

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.

A promise object has the following internal properties:

  1. 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 the state value is pending.
  • value: When resolve(value) is called.
  • error: When reject(error) is called.

A promise that is either resolved or rejected is called settled.

let promise = new Promise(function(resolve, reject) {
resolve("I am surely going to get resolved!");

reject(new Error('Will this be ignored?')); // ignored
resolve("Ignored?"); // ignored
});

Only the first one to resolve will be called and the rest will be ignored.

Promise Static Methods

Promise.all(iterable)

  • Wait for all promises to be fulfilled, or for any to be rejected.
  • If the returned promise fulfils, it is fulfilled with an array of the values from the fulfilled promises, in the same order as defined in the iterable of multiple promises.
  • If it rejects, it is rejected with the reason from the first promise in the iterable that was rejected.
  • If one of the promises in the array rejects, Promise.all() will throw the error and abort the other operations.

Promise.allSettled(iterable)

  • Wait until all promises have settled
  • Ensures all operations are complete before resolving
  • Returns a Promise that fulfils after all of the given promises is either fulfilled or rejected, with an array of objects that each describe the outcome of each promise.

Promise.any(iterable)

  • Returns a single promise that fulfils(resolves) with the value from that promise.
  • If all of the given promises are rejected, then the returned promise is rejected with AggregateError – a special error object that stores all promise errors in its errors property.

Promise.race(iterable)

  • Wait until any of the promises is fulfilled or rejected.

Promise.resolve(value)

  • Returns a new Promise object that is resolved with the given value.

Promise.reject(reason)

  • Returns a new Promise object that is rejected with the given reason.

Promise Prototype (Instance) Methods

Promise.prototype.catch()

  • Appends a rejection handler callback to the promise.
  • Returns a new promise resolving to the return value of the callback if it is called, or to its original fulfilment value if the promise is instead fulfilled.

Promise.prototype.then()

  • Appends fulfilment and rejection handlers to the promise
  • Returns a new promise resolving to the return value of the called handler(fulfillHandler or rejectionHandler), or to its original settled value if the promise was not handled.

If one or both arguments are omitted or are provided non-functions, then then will be missing the handler(s), but will not generate any errors. It passes on the last settled promise on which it was called.

Promise.resolve('Success')
.then(val=> val.toLowerCase())
.then()
// result
Promise {<fulfilled>: 'success'}
Promise.resolve('Success')
.then(val=> val.toLowerCase())
.then(val=> val)
// result
Promise {<fulfilled>: 'success'}

Promise.prototype.finally()

  • Appends a handler to the promise.
  • Returns a new promise that is resolved when the original promise is resolved.
  • The handler is called when the promise is settled, whether fulfilled or rejected.

Promise Chain

The methods Promise.prototype.then(), Promise.prototype.catch(), and Promise.prototype.finally() are used to associate further action with a promise that becomes settled.

The .then() method:-

  • takes up to two arguments.
  • the first argument is a callback function for the fulfilled case of the promise.
  • the second argument is a callback function for the rejected case.
  • Each .then() returns a newly generated promise object, which can optionally be used for chaining
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("foo");
}, 300);
});
myPromise
.then(handleFulfilledA, handleRejectedA)
.then(handleFulfilledB, handleRejectedB)
.then(handleFulfilledC, handleRejectedC);

A promise can participate in more than one nesting. Here, the transition of promiseA into a "settled" state will cause both instances of .then() to be invoked.

const promiseA = new Promise(myExecutorFunc);
const promiseB = promiseA.then(handleFulfilled1, handleRejected1);
const promiseC = promiseA.then(handleFulfilled2, handleRejected2);

Using Promises

  • Always return the promise operation and defer its handling to the next .then() handler.
const listOfIngredients = [];

doSomething()
.then((url) => {
// I forgot to return this
fetch(url)

.then((res) => res.json())
.then((data) => {
listOfIngredients.push(data);
});
})
.then(() => {
console.log(listOfIngredients);
// Always [], because the fetch request hasn't completed yet.
});

Popular Questions

Q. Why it is preferred to have a .catch() rather than having a callback in .then() for error handling?

Q. How does Promise resolve the issues caused by using Callbacks?
There are two issues with callbacks:-
1. Callback hell
2. Inversion of control

Q. Which Queue are Promises handled with and how are they different from callback handling queues?
Promises are handled with Microtask queue whereas callbacks are handled with Callback queue.

Q. What is the value of Promise.length?
It will be always one (1) due to number of constructor arguments.

Sources

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

--

--