Promises, what are they in Javascript?
Before promises?
Before promises came to Javascript, callbacks have been the means of achieving asynchronous functionality in Javascript. Callbacks basically are functions that are passed as arguments to other functions, so that they can be called when the function they were passed into as argument finishes running. Why is such technique possible in Javascript? Well, everything in Javascript is an object and also, Javascript supports First Class Functions. What is a First Class Function? According to MDN,
A programming language is said to have First-class functions when functions in that language are treated like any other variable. For example, in such a language, a function can be passed as an argument to other functions, can be returned by another function and can be assigned as a value to a variable.
So, because of this nature of Javascript, implementing callbacks is easy and straightforward, but talk about the devil - lols. Yeah, callbacks are good, but we can get into a mess with it when we nest callbacks too deeply. Let's look at an example of a callback.
import print from 'somefile';
print((err, val) => {
if (err) {
console.log(err);
return;
}
// do something with val
});The code above is very simple and straight forward. But this is the very best case scenario of callbacks. Let's see an example of callback hell.
callback1((err, data1) => {
callback2((err, data2) => {
callback3((err, data3) => {
// and so on...
});
});
});The nesting will become unwieldy and you wouldn't know where you are in the callbacks. But, holla, the days of callbacks came to an end when promises got introduced.
Now, mortals! Welcome Promises
What are promises? According to MDN,
A Promise is an object that's returned by a function that has not yet completed its work. The promise literally represents a promise made by the function that it will eventually return a result through the promise object.
This represents the very simplistic explanation to what Promises are. The Promise constructor is used to create instances of a promise object which is an object that holds the state of the operation of the function. The Promise constructor accepts a function called the executor which takes two arguments (resolve, reject) which are callbacks (Ahhhha, callbacks again). When the promise is created, the executor runs immediately and starts a process which may not return immediately, so the promise constructor returns an object which represents the internal states of the process running. The object returned by the constructor has the state and result properties. The state is pending and result is undefined initially. When the executor finishes processing, it can resolve with a value or reject with an error. Let's look at some code.
function genPromise() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Hello world"), 5000);
});
genPromise().then(val => console.log(val));
console.log("I will be logged first");
}From the code snippet, the genPromise function returns a promise object, and there are two methods then and catch that can be used to get resolved values or rejected errors from within the executor. The then function can also be used to catch rejected errors. If you run the code, "I will be logged first" will be logged before "Hello world" because that is why Promises are good, they are asynchronous. They don't block the Javascript thread. Because "Hello world" has been set out to resolve after 5s, the Javascript process continues to the next line of code while the Promise function gets moved to an internal queue and run in the next event loop of the process. This is a basic high level introduction to Promises, I will be writing soon about what and how we can use Promises and introduction to async/await keywords. Thanks.