Open In App

How to Implement a Custom Promise in JavaScript ?

Last Updated : 30 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

A custom Promise in JavaScript encapsulates asynchronous operations. It takes two parameters, resolves and rejects functions, and executes an async task. Resolve is called on success with the result, while reject is called on failure with an error.

Using Class Syntax

In this approach, we are creating a custom promise using Class Syntax. The class encapsulates asynchronous operations, handling resolution, rejection, and chaining. It provides a concise and organized structure for promise implementation in JavaScript.

Syntax:

class Name {
constructor(var) {
this.var = var;
}
}

The Name class has a constructor that initializes an instance with a property var. This property stores a value passed during object creation, encapsulating it within the class instance.

Example: To demonstrate the CustomPromise class implements a basic promise with asynchronous resolution. The then method creates and returns a new promise, handling fulfilment or rejection asynchronously.

Javascript




class CustomPromise {
  constructor(executor) {
    this.state = "pending";
    this.value = null;
    this.handlers = [];
 
    const resolve = (result) => {
      if (this.state === "pending") {
        this.state = "fulfilled";
        this.value = result;
        this.handlers.forEach((handler) => {
          handler.onFulfilled(result);
        });
      }
    };
 
    const reject = (error) => {
      if (this.state === "pending") {
        this.state = "rejected";
        this.value = error;
        this.handlers.forEach((handler) => {
          handler.onRejected(error);
        });
      }
    };
 
    executor(resolve, reject);
  }
 
  then(onFulfilled, onRejected) {
    return new CustomPromise((resolve, reject) => {
      if (this.state === "fulfilled") {
        setTimeout(() => {
          try {
            resolve(onFulfilled(this.value));
          } catch (error) {
            reject(error);
          }
        }, 0);
      } else if (this.state === "rejected") {
        setTimeout(() => {
          try {
            reject(onRejected(this.value));
          } catch (error) {
            reject(error);
          }
        }, 0);
      } else {
        this.handlers.push({ onFulfilled, onRejected });
      }
    });
  }
}
 
const promise = new CustomPromise((resolve, reject) => {
  setTimeout(() => resolve("Hello, GeeksforGeeks"), 500);
});
 
promise.then((result) => console.log(result));


Output

Hello, GeeksforGeeks

Using Factory Function

A factory function is a function that returns an object or a function. In the context of a custom promise, a factory function creates and returns a custom promise object with specified behaviours.

Syntax:

function createRobot(name) {
return {
name: name,
talk: function () {
console.log('My name is '
+ name + ', the robot.');
}
};
}

Example: This createCustomPromise factory function generates a custom promise-like object with `then`, `catch`, and `finally` methods.

Javascript




function createCustomPromise(delay, shouldResolve) {
    return {
        then(onFulfilled, onRejected) {
            return createCustomPromiseInternal(
                delay,
                shouldResolve,
                onFulfilled,
                onRejected
            );
        },
 
        catch(onRejected) {
            return this.then(null, onRejected);
        },
 
        finally(onFinally) {
            return this.then(
                (result) => {
                    onFinally();
                    return result;
                },
                (error) => {
                    onFinally();
                    throw error;
                }
            );
        },
    };
}
 
function createCustomPromiseInternal(
    delay,
    shouldResolve,
    onFulfilled,
    onRejected
) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (shouldResolve) {
                try {
                    resolve(
                        onFulfilled &&
                        onFulfilled(`
            Promise resolved successfully
            `)
                    );
                } catch (error) {
                    reject(error);
                }
            } else {
                try {
                    reject(onRejected && onRejected("Promise rejected"));
                } catch (error) {
                    reject(error);
                }
            }
        }, delay);
    });
}
 
const promise = createCustomPromise(500, true);
 
promise
    .then((result) => console.log(result))
    .catch((error) => console.error(error))
    .finally(() => console.log("Finally block executed"));


Output:

Promise resolved successfully
Finally bloxk executed


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads