Javascript Promise became popular when it was introduced. Javascript promise is mainly used to handle asynchronous tasks. In this article, we will deep dive into promise through examples.
Promise state:
A Javascript promise can have only one state in either fulfilled or rejected.
A promise in a state of fulfillment or rejection is called a promise settled.
Example#1
Promise with resolved state
// Asnc function always return Promsie with resolve or resolve state
async function getMyName(){
return "Vijendra Rana"
}
//OR
function getMyName(){
return new Promise((resolve)=>{
resolve("Vijendra Rana")
})
}
//or
function getMyName(){
return Promise.resolve("Vijendra Rana")
}
Example#2
Promise with rejected state
// Asnc function always return Promsie with resolve or resolve state
async function getMyName(){
//Throw here return Promise with rejected state with reason
throw Error("Name not found")
}
//OR
function getMyName(){
return new Promise((_,reject)=>{
reject(Error("Name not found"))
})
}
//or
function getMyName(){
return Promise.resolve(Error("Name not found"))
}
//Error - when promise rejected, provide proper reason using Error
Example#3
Get a response from resolved Promise - By using then() chain method
getMyName().then(res =>{
console.log("------",res)
})
Example#4
Handle rejected the promise. catch() chain method
getMyName().then(res =>{
console.log("------",res)
})
.catch(err =>{
//log the reasons
})
Example#5
in then(), we can add resolve and reject handler
//Reject Hanndler
async function getAllNames(id) {
if (id) {
return ["a", "b", "c"];
} else {
throw new Error("id is undefined");
}
}
//every Promise has resolve and reject hander
const namePromise = getAllNames(12);
// namePromise
// .then((res) => {
// console.log(res);
// })
// .catch((err) => {
// console.warn(err);
// });
console.log(typeof namePromise);
namePromise.then(
() => {
console.log("Resolved");
},
() => {
console.log("Unresolved");
}
);
Example#6
finally() to clean up purpose.
//finally to clean up
async function getMovies(id) {
if (id) {
return ["1", "2", "3"];
} else {
throw new Error("Id req");
}
}
getMovies(12)
.then((res) => {
if (!res) {
throw Error("Unsuccessful attempt");
} else {
console.log("data", res);
}
})
.catch((err) => {
console.log("error-->", err);
throw new Error("....");
})
.finally(() => {
console.log("more clean up work");
});
Example#7
Return reject promise from resolve handler when the response is not ok.
//Promise to reject
async function getMovies(id) {
if (id) {
return ["1", "2"];
} else {
return [];
}
}
getMovies().then((res) => {
if (res.length === 0) {
return Promise.reject(new Error("unsuccessful response"));
}
}).catch((err) =>{
console.warn('---!!!!',err);
});
Example#8
Create Promise with Promise constructor.
//Promise Constructor
// const promise = new Promise((resolve, reject) => {
// // do some async operation then return promise with resolved state
// setTimeout(() => {
// resolve();
// }, [1000]);
// });
//refactor to sleep
// function sleep(ms) {
// return new Promise((resolve) => {
// // do some async operation then return promise with resolved state
// setTimeout(() => {
// resolve();
// }, [ms]);
// });
// }
//further refactor
function sleep(ms) {
return new Promise((resolve) => {
// do some async operation then return promise with resolved state
setTimeout(resolve, ms);
});
}
//resolve invoked jsut after constructor called not an asynchronous call so if
function Rejectsleep(ms) {
return new Promise((resolve) => {
throw Error("+++++");
setTimeout(resolve, ms);// This line will not be reachable
});
}
sleep(1000)
.then(() => {
console.log("Resolved");
})
.catch((err) => {
console.log("Rejected from resolved promise");
});
Rejectsleep(1000)
.then(() => {
console.log("Resolved");
})
.catch((err) => {
console.log("Rejected from resolved promise");
});
Example#9
Convert callback to Promise
//convert call back to promise
//read file from fs lib, Node api use callback heavily
// import { readFile } from "fs";
const fs = require("fs");
//this is callback based
// fs.readFile(__filename, "utf-8", (error, contents) => {
// if (error) {
// console.error(error);
// } else {
// console.log(contents);
// }
// });
//convert to Promise based app
function readFile(path, encoding) {
return new Promise((resolve, reject) => {
fs.readFile(path, encoding, (error, contents) => {
if (error) {
reject(error);
} else {
resolve(contents);
}
});
});
}
readFile(__filename, "utf8").then(
(contents) => {
console.log(contents);
},
(error) => {
console.error(error);
}
);
Example#10
Promise.race() - get the fastest settled promise
//Promise.race()
//examplep-1
function resolveAfter(ms, value) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(value);
}, [ms]);
});
}
// const pA = resolveAfter(1000, "A");
// const pB = resolveAfter(2000, "B");
// const PResult = Promise.race([pA, pB]);
// PResult.then((val) => {
// console.log(val);
// });
//Least use of Race method but in one case
function timeout(ms, promise) {
let timeoutId;
const timeoutPromise = new Promise((_, reject) => {
timeoutId = setTimeout(() => {
reject(Error(`Operation timed out after ${ms}`));
}, ms);
});
return Promise.race([promise, timeoutPromise]).finally(() => {
clearTimeout(timeoutId);
});
}
const promise = resolveAfter(1000, "Promise A");
timeout(5000, promise).then(
(value) => {
console.log(value);
},
(error) => {
console.error(error);
}
);
Example#11
Promise.all() - get all promises when all API calls parallel
//Promise.all
async function getMovieTitle(id){
return "Iron Man"
}
async function getMovieId(dir, actor){
return 1
}
// getMovieId("Rachel","RJD").then((res) =>{
// if(res){
// getMovieTitle(res).then((t) =>{
// console.log('++++',t);
// })
// }
// })
//If both are independent call then call Parallely
const promsies = Promise.all([
getMovieId("Rachel","RJD"),
getMovieTitle(1)
])
// console.log('Fullfilled Promsie',promsies);
promsies.then(([id,title]) =>{
// const id = res[0]
// const title = res[1]
console.log('Id',id, 'Title',title);
}).catch(err =>{
console.log(err);
}).finally(() =>{
//do some clean up work
})
//in order Promise to be fullfilled , all promise must be fullfilled
Example#12
If any promise failed from Promsie.all() then no return one Promsie with rejected state. So Promsie.allSettled()
//Promsie.allSettled
async function getMovieTitle(id) {
throw Error("Something Wrong!!");
}
async function getMovieId(dir, actor) {
return 1;
}
//Promise.allSettled always return settlled promise
Promise.allSettled([getMovieId("Rachel", "RJD"), getMovieTitle(1)]).then(
([id, title]) => {
if (id.status === "fulfilled") {
console.log(id.value);
}
if (title.status === "fulfilled") {
console.log(title.value);
}
}
);
Example#13
Promise. any() - > In the real word, API failed. To make it resilient we can use Promise.any()
//Promsie.any() to make more resilinet in api down time
var promises = [
Promise.reject(Error("Fail#1")),
Promise.reject(Error("Fail#2")),
// Promise.resolve(2),
];
// Promsie.any return fullfilled promise if any Promise is fullfilled
Promise.any(promises).then(
(value) => {
console.log("fullfilled ", value);
},
(error) => {
console.warn(error.errors);
}
);
Example#14
Async/Await - We can use better readable code with async/await keyword from JS.
//Async/Await
function getMovies() {
return new Promise((resolve, reject) => {
resolve(["a", "b", "c"]);
// reject(Error("Erorr Occured"));
});
}
function getMovies2() {
return new Promise((resolve) => {
resolve(["a1", "b1", "c1"]);
});
}
async function main() {
try {
//it is a sequential api call
// const movies = await getMovies();
// const movies2 = await getMovies2();
//parrallel
const [movies, movies2] = await Promise.all([
await getMovies(),
await getMovies2(),
]);
console.log("+++++", movies, movies2);
} catch (error) {
console.log("Some error occured");
}
}
main();
I hope it will help to understand and write promise-based codes in JS.
Next, we will deep dive into Async/Await. Check my articles to know more about technical stuff.
Happy coding :)
Top comments (0)