Callbacks :-
A callback is a function given to another function to be called after some operation completes.It helps handle asynchronous tasks like API calls or events.
function greet(name, callback) {
console.log("Hello " + name);
callback();
}
function sayBye() {
console.log("Goodbye!");
}
//Here sayBe() function is passed to greet function which can executed by greet function later
greet("Amit", sayBye);
Prons of Callbacks Function :-
Simple to understand
Good for Event Handling
work well with small async operation
Cons of Callback Function :-
When mutiple async operation depedend on each other then it forms a callback hell which difficult to read and debug the deep nesting program.
we have to handle error handling in every callback function which is very difficult to maintain.
Give control of callback function to some other function also known as inversion of control . Due to which user looses the control how many times function run the callback function
By calling mutiple nested callback function it created a call back structure which is also known as pyramid of doom which is difficult to debug and maintain.
Example of Callback Hell :-
function step1(callback) {
setTimeout(() => {
console.log("Step 1 done");
callback();
}, 1000);
}
function step2(callback) {
setTimeout(() => {
console.log("Step 2 done");
callback();
}, 1000);
}
function step3(callback) {
setTimeout(() => {
console.log("Step 3 done");
callback();
}, 1000);
}
function step4(callback) {
setTimeout(() => {
console.log("Step 4 done");
callback();
}, 1000);
}
//This structure is known as callback Hell
step1(() => {
step2(() => {
step3(() => {
step4(() => {
console.log("All steps completed");
});
});
});
});
Promises :-
A Promise is an object in JavaScript that represents the eventual completion or failure of an asynchronous operation.
Promises has 3 states :-
1.Pending (Initial State) :- Pending is the initial state of a Promise where the asynchronous operation is still in progress and neither resolved nor rejected.
2.Fullfilled (Resolved State) :- Fulfilled is the state of a Promise when the asynchronous operation completes successfully and resolve() is called with a value.
3.Rejected :- Rejected is the state of a Promise when the asynchronous operation fails and reject() is called with an error.
Problem solved using promises :-
1.Promises solve callback hell by avoiding deeply nested callbacks (Pyramid of Doom) and enabling flat, readable chaining using .then().
2. Promises provide centralized error handling using .catch(), so we don’t need to handle errors at every nested level.
3. Promises solve inversion of control by guaranteeing that a promise can resolve or reject only once and its state cannot be changed after settlement, making async behavior predictable.
const myPromise = new Promise((resolve, reject) => {
let success = true;
if (success) {
resolve("Operation Successful");
} else {
reject("Operation Failed");
}
});
myPromise
.then(result => {
console.log(result);
})
.catch(error => {
console.log(error);
});
A Promise is created .
If success is true then resolve() is called and Promise becomes fullfilled.
If success is false then reject() is called and Promise becomes rejected.
.then() runs when resolved.
.catch() runs when rejected.
Promises Method :-
1.Promise.resolve() :- It create a promise that is already fulfiiled
const p = Promise.resolve("Success");
p.then(data => console.log(data)); //Success
2.Promise.reject() :- It creates a promise that is already rejected.
const p = Promise.reject("Error occurred");
p.catch(err => console.log(err));//Error occurred
3.then() :- It is used to handle fullfilled value
const p = new Promise(resolve => {
resolve("Data received");
});
p.then(data => console.log(data)); //Data recieved
4.catch() :- It is used to handle the errors
const p = new Promise((resolve, reject) => {
reject("Something went wrong");
});
p.catch(err => console.log(err));
5.finally() :- It runs always irrespective of success or failure
Promise.resolve("Done")
.then(data => console.log(data)) //Done
.finally(() => console.log("Cleanup done")); //Cleanup done
6. Promise.all() :-It waits for all promised to succeed. If any one promise fails then it will rejected the whole the promise
const p1 = Promise.resolve("A");
const p2 = Promise.resolve("B");
Promise.all([p1, p2])
.then(results => console.log(results))
.catch(err => console.log(err));
7.Promise.allSettled() :- It waits for all the promises to be settled either resolve or reject
const p1 = Promise.resolve("A");
const p2 = Promise.reject("B failed");
Promise.allSettled([p1, p2])
.then(results => console.log(results));
/*
[
{ status: "fulfilled", value: "A" },
{ status: "rejected", reason: "B failed" }
]
*/
8. Promise.race() :- It will wait for the first promise to be settle either resolve or reject
const p1 = new Promise(resolve => setTimeout(() => resolve("Fast"), 1000));
const p2 = new Promise(resolve => setTimeout(() => resolve("Slow"), 3000));
Promise.race([p1, p2])
.then(result => console.log(result));
9. Promise.any() :- It return the first successfull promise result and ignores the rejection until all the promises are fail . If all promises are reject then it will throw AggregateError
const p1 = Promise.reject("Fail 1");
const p2 = Promise.resolve("Success");
const p3 = Promise.reject("Fail 2");
Promise.any([p1, p2, p3])
.then(result => console.log(result)) //success
.catch(err => console.log(err));
Promise.any([p1, p2, p3])
.then(result => {
console.log("Success:", result);
})
.catch(error => {
console.log("All errors:", error.errors);
});
/*
Aggregate Error
All errors: [
"Server 1 failed",
"Server 2 failed",
"Server 3 failed"
]
*/