Skip to main content

JavaScript Promise (Live Playground)

Promise in JavaScript is a powerful way to handle asynchronous operations. They provide a cleaner and more manageable approach compared to using callbacks.

Creating Promise

To create a Promise, use the Promise constructor and pass a single argument, known as the executor function. The executor function takes two parameters: a resolve function and a reject function.

Example:

const myPromise = new Promise((resolve, reject) => {
// Asynchronous operation here...
});

Using the resolve and reject Functions

Call the resolve function when the asynchronous operation is successful and pass the result as an argument. Call the reject function when the operation fails and pass the error as an argument.

Example:

const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = true; // Simulate success or failure

if (success) {
resolve('Data fetched');
} else {
reject('Error fetching data');
}
}, 1000);
});
};

Consuming Promise

Use the then method to attach callbacks that will be called when the Promise is fulfilled. Use the catch method to attach callbacks that will be called when the Promise is rejected.

Example:

fetchData()
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});
Live Playground, Try it Yourself

Promise States

A Promise can be in one of the following states:

  • Pending: The initial state of the Promise. Neither fulfilled nor rejected.
  • Fulfilled: The Promise has successfully completed and has a resulting value.
  • Rejected: The Promise has failed, and a reason for the failure is provided.

Transitioning Between States

When you create a Promise, it is in the pending state. It transitions to the fulfilled or rejected state by calling the resolve or reject functions, respectively, in the executor function.

Example:

const myPromise = new Promise((resolve, reject) => {
// Asynchronous operation here...

if (/* operation successful */) {
resolve(result);
} else {
reject(error);
}
});

Consuming Promise States

When a Promise is in the fulfilled state, the callbacks attached with the then method are executed. When a Promise is in the rejected state, the callbacks attached with the catch method are executed.

Example:

myPromise
.then(result => {
console.log('Success:', result);
})
.catch(error => {
console.error('Error:', error);
});

Promise State Immutability

Once a Promise transitions from the pending state to either the fulfilled or rejected state, its state cannot change. This ensures that the Promise's value or reason remains consistent throughout its lifecycle.

Example:

const myPromise = new Promise((resolve, reject) => {
resolve('First resolve');
resolve('Second resolve'); // This call is ignored
reject('First reject'); // This call is ignored
});
Live Playground, Try it Yourself

Chaining Promises in JavaScript

Chaining Promises in JavaScript helps you to manage multiple asynchronous operations sequentially.

Chaining Promises

Chaining Promises involves attaching multiple then and catch methods to a single Promise. When a Promise is fulfilled, the next then method in the chain is called, and when a Promise is rejected, the next catch method is called.

Example:

const myPromise = new Promise((resolve, reject) => {
resolve('Initial Value');
});

myPromise
.then(value => {
console.log('First then:', value);
return value + ' - Second then';
})
.then(newValue => {
console.log(newValue);
return newValue + ' - Third then';
})
.then(finalValue => {
console.log(finalValue);
})
.catch(error => {
console.error('Error:', error);
});
Live Playground, Try it Yourself

Error Handling in Promise Chains

If a Promise is rejected or an error is thrown in a then method, the chain skips all remaining then methods and proceeds to the next catch method.

Example:

const myPromise = new Promise((resolve, reject) => {
resolve('Initial Value');
});

myPromise
.then(value => {
console.log('First then:', value);
throw new Error('An error occurred');
})
.then(newValue => {
console.log('This will not be executed');
})
.catch(error => {
console.error('Error:', error.message);
});
Live Playground, Try it Yourself

Returning Promises in Chains

You can return a Promise from a then method, allowing you to perform asynchronous operations in sequence.

Example:

const myPromise = new Promise((resolve, reject) => {
resolve('Initial Value');
});

function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Data fetched');
}, 1000);
});
}

myPromise
.then(value => {
console.log('First then:', value);
return fetchData();
})
.then(data => {
console.log('Data:', data);
})
.catch(error => {
console.error('Error:', error);
});
Live Playground, Try it Yourself

Promise Error Handling

Handling errors in JavaScript Promises is essential to create resilient applications.

Using catch

The catch method is used to handle errors or rejected Promises. It is called when an error is thrown or a Promise is rejected in the preceding chain.

Example:

const myPromise = new Promise((resolve, reject) => {
reject('An error occurred');
});

myPromise
.then(value => {
console.log('Value:', value);
})
.catch(error => {
console.error('Error:', error);
});
Live Playground, Try it Yourself

Using finally

The finally method is called regardless of whether the Promise is fulfilled or rejected. It is useful for performing cleanup tasks or other operations that should occur no matter the outcome.

Example:

const myPromise = new Promise((resolve, reject) => {
reject('An error occurred');
});

myPromise
.then(value => {
console.log('Value:', value);
})
.catch(error => {
console.error('Error:', error);
})
.finally(() => {
console.log('Finished processing the Promise');
});
Live Playground, Try it Yourself

Handling Errors in a Promise Chain

If an error is thrown or a Promise is rejected in a chain, the execution skips to the next catch method. This allows for centralized error handling.

Example:

const myPromise = new Promise((resolve, reject) => {
resolve('Initial Value');
});

myPromise
.then(value => {
console.log('First then:', value);
throw new Error('An error occurred');
})
.then(newValue => {
console.log('This will not be executed');
})
.catch(error => {
console.error('Error:', error.message);
});
Live Playground, Try it Yourself

Conclusion

Promise provides an elegant way to handle asynchronous operations in JavaScript. By creating and using Promise, you can avoid callback hell and write more maintainable and readable code.