Why is this an issue?

In JavaScript, a promise is an object representing the eventual completion or failure of an asynchronous operation. It is a way to handle asynchronous operations more elegantly and avoid the "callback hell".

A promise can be in one of three states:

The basic syntax for creating a promise in JavaScript is as follows:

const myPromise = new Promise((resolve, reject) => {
  // Asynchronous operation
  // If the operation is successful, call resolve(value)
  // If the operation fails, call reject(error)
});

However, when it comes to immediately resolving or rejecting states, creating a new promise with the Promise constructor and manually calling resolve or reject makes the code verbose and more difficult to read.

const result = new Promise(resolve => resolve(42)); // Noncompliant: Redundant to explicitly create a promise to resolve 42
result.then(value => {
  console.log(value); // Output: 42
});

Instead, a promise can be created with Promise.resolve. It is typically used when you want to create a new promise that is already resolved with a certain value. It is commonly used to wrap synchronous values or functions into promises.

How to fix it

If you already have a synchronous value that you want to convert into a promise, using Promise.resolve is more concise and straightforward. It immediately creates a promise that is already resolved with the provided value.

const result = Promise.resolve(42);
result.then(value => {
  console.log(value); // Output: 42
});

Similarly, if you have an error or an exceptional condition and want to create a promise that is immediately rejected with that error, using Promise.reject is more straightforward. It creates a promise in the rejected state with the provided error.

const error = new Error('Something went wrong');
const promise = Promise.reject(error);

If you have a condition and want to create a promise that is either resolved or rejected based on that condition, using Promise.resolve or Promise.reject helps make the code more readable and concise.

function fetchData() {
  if (cache) {
    return Promise.resolve(cache);
  } else if (shouldFetchData()) {
    return fetchDataFromServer()
        .then(data => {
            cache = data;
            return data;
        });
  } else {
    return Promise.reject(new Error('Data fetch is not required'));
  }
}

When you have a promise chain and want to introduce an intermediate step with an immediately resolved value, using Promise.resolve allows you to continue the chain without introducing unnecessary complexity.

const data = cache ? cache : fetchData();

return Promise.resolve(data) // data may be a Promise or not, we need to wrap it
    .then(data => {
        return sanitizeData(data);
    })

Using Promise.resolve and Promise.reject is particularly useful when you want to simplify the creation of promises with immediately resolved or rejected states. They provide a cleaner and more direct approach compared to creating a new promise with the Promise constructor and manually calling resolve or reject.

Resources

Documentation