Definition
In simple terms, a promise is a response object that is returned from an asynchronous operation. It allows you to write asynchronous code in a synchronous style, making it easier to manage and reason about.
A Promise has three states: pending, fulfilled, and rejected. When a Promise is first created, it is in the pending state. Once the asynchronous operation is complete, the Promise transitions to either the fulfilled or rejected state, depending on whether the operation was successful or not.
Most of the time promises are used instead of callback functions.
For example
myfucntion(testParam).then(successCallback, failureCallback)
Why would you use Promises?
There are several benefits of using promises in your code over callbacks.
Never invoked before completion
By using the then() keyword we ensure that the function has finished running its processes before it is called. Whether the async operation fails or succeeds a then() method could be invoked.
Multiple Callbacks can be triggered
The then() keyword also allows us to add multiple callbacks, one after the other in the order in which they were added to the code.
This leads us nicely to our next benefit: Chaining.
Chaining
It's very common that in our daily development we will need to chain multiple operations to run back to back. This is called building a promise chain.
You can then use the then
and catch
methods to handle the fulfilment or rejection of the Promise. The then
method is called when the Promise is fulfilled, and the catch
method is called when the Promise is rejected.
Promise chains use results from previous successful operations in each subsequent operation in the chain. Using the then keyword returns a promise in itself, which represents the result objection from any callback functions that were used. Basically creating an asynchronous chain of promises.
Previously, before promises came into play, to do several asynchronous callback functions in a row would require a pyramid of functions. For example:
functionOne(function (result) {
functionTwo(result, function (result2) {
functionThree(result, function (result3) {
console.log(`Final result: ${result3}`);
}, failedCallback);
}, failedCallBack);
}, failedCallback);
However, this has been drastically simplified and made easier to read with promises:
functionOne()
.then(function (result) {
return functionTwo(result);
})
.then(function (result2) {
return functionThree(result3)
})
.then(function (result3) {
console.log(`Final result: ${result3}`);
})
.catch(failedCallback);
This can be simplified even further with arrow functions, as long as we are always returning the results:
functionOne()
.then((result) => return functionTwo(result))
.then((result2) => return functionThree(result3))
.then((result3) => console.log(`Final result: ${result3}`))
.catch(failedCallback);
In the same manner, as above, chaining can also happen after a catch. Any errors will be propagated through the chain.
Promises are a useful tool for handling asynchronous code in JavaScript, and are often used in conjunction with other asynchronous patterns such as async/await.
I hope you found this helpful. Please let me know in the comments below if you found this useful, how you use promises and if there are any topics you would like me to write about in the future.
Until next time ๐โโ๏ธ