MDN Definition: The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.
To simplify MDN's definition, promises in Javascript are Objects that return two callback functions. These callback functions are called resolve and reject. Promises also have states, pending, fulfilled, rejected.
The Anatomy of A Promise
const sayHi = new Promise((resolve, reject) => {
resolve("Hello there!")
})
sayHi.then((value) => {
console.log(value)
})
If you're new to Javascript this may look like gibberish to you but the fact is, it is gibberish. If I could describe Javascript in two words I would describe it as beautiful gibberish.
We create the promise using new Promise and pass in the two callback functions resolve and reject, these can be named anything you want. We then end the promise by calling it's resolve callback function and passing it a value. At this point the promise is in a settled state.
To be able to use the value that the promise returns, we need to use the then method on the promise instance. Which in turns returns another promise but we won't get deep into that. We should now have access to that promise's return value.
Promise Error Handling
The problem with our current promise is that it will always return with a fulfilled state because we currently aren't handling for any errors. Lets fix that.
const add = (num1, num2) => {
return new Promise((resolve, reject) => {
if (typeof num1 !== 'number' || typeof num2 !== 'number') {
reject("Both values must be a number!")
} else {
resolve(num1 + num2)
}
})
}
add(2, "Not a number").then((total) => {
console.log(total)
}).catch(error => {
console.log(error)
})
This returns "Both values must be a number!". For simplicity's sake ignore the add function and focus on the core body of the promise. Within the promise scope we created an if statement to check for possible invalid datatypes. Notice we call the reject function after finding a string, this immediately ends the promise and sets it to a rejected state.
Having the promise end in a rejected state allows the catch method on the promise instance to be used. The then method gets completely ignored and only the error is returned through catch.
Promises are Asynchronous
As the header states, promises are asynchronous. Which means they will continue to run in the background while your program traverses. Here's a quick bit of code that explains it better.
const loadHugeCatImage = new Promise((resolve, reject) => {
setTimeout(()=>{}, 10000)
resolve("Cat Image Loaded!")
})
loadHugeCatImage.then((message) => {
console.log(message)
})
console.log("I should be second!")
Logic tells us that "Cat Image Loaded!" will be outputted to the console before "I should be second!", due to the order of execution. In reality, even though we called the promise, the program will continue to run and execute console.log("I should be second!")
before console.log("Cat Image Loaded!")
. This is because of the promise's asynchronous behavior. Is incredibly useful for loading huge amounts of data in a website without slowing down the user.
This was a very simple way of explaining what promises are. If you want to know more feel free to visit MDN Promises. Thank you for reading!
Top comments (0)