Author: M Abo Bakar Aslam
Promises
Promises are a built-in feature in JavaScript used to handle asynchronous operations in a structured and manageable way. They provide a cleaner alternative to callbacks, especially when dealing with complex asynchronous flows.
A Promise is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value.
1. Promise Basics
In JavaScript, Promise is a constructor function. When you use it, you create a new promise object.
A Promise connects two parts:
- Producing Code: Performs the asynchronous task
- Consuming Code: Waits for and handles the result
A Promise has three states:
- Pending: Initial state (neither fulfilled nor rejected)
- Fulfilled: Operation completed successfully
- Rejected: Operation failed
2. Promise Structure
A Promise is created using an executor function, which takes two callback functions:
resolve()→ called when the operation is successfulreject()→ called when an error occurs
The result is handled using .then() in consuming code.
// creating promise object "myPromise" that is an instance of Promise constructor
// Promise constructor takes a single argument, which is the executor/anonymous function
// myResolve and myReject are two callback functions
let myPromise = new Promise(function(myResolve, myReject) {
// "Producing Code" (May take some time)
//only one of following function would be called
myResolve(value); // calling myResolve when successful and send "value" to the myResolve
myReject(error); // calling when error and send "error" to the myReject
})
// "Consuming Code" (Must wait for a fulfilled Promise)
myPromise.then(
function(value) { /* code if successful */ }, //first parameter is for myResolve. Receive "value" from above promise
function(error) { /* code if some error */ } //second parameter is for myReject. Receive "error" from above promise
)Example Code 1:
- The promise is created with an executor function.
- Only one of the callbacks (resolve or reject) is executed.
- Once a callback is executed, control moves to the consuming part.
- The
.then()method handles both success and error cases.
//creating promise object
let prom = new Promise(function(resolve, reject){
// Asynchronous operation or logic
let x = 10
if(x == 10){
let y = "done"
resolve(y) //calling resolve() and then control will go to "then" section
reject(y)//never run because control will not back here after calling above resolve()
}else{
let z="error"
reject(z)
}
}
)
prom.then(
function(resolveOut){//function will receive value of "y" in "resolveOut"
console.log("Result of Resolve", resolveOut) //display value of "resolveOut"
},
function(rejectOut){//function will receive value of "z" in "rejectOut"
console.log("Result of Reject", rejectOut) //display value of "rejectOut"
}
)3. Promise with Conditional Logic
Example Code 2:
- A condition determines whether to resolve or reject the promise.
- If the condition is true, the promise is fulfilled.
- Otherwise, it is rejected.
- The result is passed to the corresponding handler in
.then().
timeProm = new Promise(function(ourResolve, ourReject){
let ourMessage = "setTimeout by using Promises" //it should be displayed after 3 seconds
//now use setTimeout() to send ourMessage to ourResolve
if(ourMessage != ""){
//ourResolve is callback function having an argument
//Therefore, we need to define another executor/anonymous function
//inside this function, we call our callback function with some parameter
//it means
//setTimeout(ourResolve(ourMessage), 3000) //logical error
setTimeout(function(){ourResolve(ourMessage)}, 3000) //correct instead of above line
}else{
ourReject("Error for Message")
}
})
timeProm.then(
function(receiveMessage){console.log("Message: ", receiveMessage)},
function(receiveError){console.log("Error: ", receiveError)}
)4. Using Promise with setTimeout()
Example Code 3:
- A delay is introduced using an asynchronous operation.
- The result is sent to the resolve function after a specified time.
- The promise ensures that the consuming code waits for the delayed result.
- This demonstrates how promises can replace traditional callback usage with timing functions.
const fileProm = new Promise(
function(resolve, reject){
const fsProm = require('fs')
fsProm.readFile('example1.txt', 'utf8', (error, data)=>{
//OR you can also use below line. Executor function is used here instead of arrow function
//fsProm.readFile('example1.txt', 'utf8', function(error, data){
if(error){
errorMessage = "This is error message"
reject(errorMessage)
}else{
resolve(data)
}
})
}
)
fileProm.then(
function(data){console.log("Data Message: ", data)},
function(errorMessage){console.log("Error Message: ", errorMessage)}
)5. Promise with File Handling
Example Code 4:
- A file is read asynchronously.
- If an error occurs, the promise is rejected.
- If the operation succeeds, the promise is resolved with file data.
- The consuming code processes either the data or the error.
6. Important Characteristics of Promises
- A promise can be resolved or rejected only once.
- Once settled (fulfilled or rejected), its state cannot change.
- It improves readability compared to nested callbacks.
- It separates logic into producing and consuming parts.
7. Advantages of Promises
- Avoids callback nesting (callback hell)
- Improves code readability and structure
- Handles asynchronous operations more effectively
- Provides better error handling mechanisms
8. Limitations of Promises
- Can still become complex with multiple chained operations
- Requires understanding of asynchronous behavior
- Debugging can be harder than synchronous code
9. Modern Approach
Promises are often used with:
.then()chaining.catch()for error handling.finally()for cleanup tasks
However, modern JavaScript commonly uses:
- Async/Await
This approach is built on top of promises and provides a more synchronous-like structure for asynchronous code.
10. Summary
- Promises represent the result of an asynchronous operation.
- They link producing code with consuming code.
- They improve readability and maintainability.
- They are widely used in modern JavaScript development.