π§ Core Concepts
Here we will be looking into these Concepts
Callback basics βοΈ
Callback vs function execution βοΈ
Promise creation βοΈ
Chaining βοΈ
Return flow βοΈ
Error handling βοΈ
Async behavior βοΈ
Function Execution vs Reference
step3(); // Executes immediately
step3; // Function reference (does nothing)
() => step3(); // Function that can be executed later
π Key idea:
()β executes nowfunction reference β can be executed later
arrow function β wrapper to delay execution
πΉ Callbacks
Basic Example
function processUser(name, callback) {
console.log("Processing " + name);
callback(name);
}
function sayHello(name) {
console.log("Hello " + name);
}
processUser("Mithilesh", sayHello);
Callback Hell
step1(() => {
step2(() => {
step3();
});
});
β Problems:
Nested structure
Hard to read
Hard to debug
πΉ Promises
Creating a Promise
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Data received");
}, 2000);
});
}
Using a Promise
getData()
.then((data) => {
console.log(data);
})
.catch((err) => {
console.log(err);
});
resolve vs reject
resolve("Success"); // goes to .then()
reject("Error"); // goes to .catch()
πΉ Promise Chaining
step1()
.then(() => step2())
.then(() => step3())
.catch(console.error);
Important Rule
.then()always expects a function
.then(step2) // passes result to step2
.then(() => step2()) // ignores result, runs step2
.then(console.log) // logs result
πΉ Return Flow (VERY IMPORTANT)
Correct
.then((res) => {
return step2(res);
})
Wrong
.then((res) => {
step2(res); // β no return
})
π Result: next .then() gets undefined
Example
Promise.resolve("A")
.then((res) => {
console.log(res);
return "B";
})
.then((res) => {
console.log(res);
});
Output:
A
B
Missing Return Example
Promise.resolve("A")
.then((res) => {
console.log(res);
"B"; // no return
})
.then((res) => {
console.log(res);
});
Output:
A
undefined
πΉ Promise vs Value
return "B"; // plain value
return Promise.resolve("B"); // Promise
π Both behave the same in .then()
πΉ Nested Promise Trap
return step2(res).then((data) => {
console.log(data);
});
π If no return β next .then() gets undefined
Correct
return step2(res).then((data) => {
console.log(data);
return data;
});
πΉ Error Handling
Throw inside .then()
.then(() => {
throw new Error("Boom");
})
.catch((err) => {
console.log(err.message);
});
π throw = reject
Important Flow
then β then β throw β catch
.then(success, error) vs .catch()
.then(success, error) // β not recommended
.catch(error) // β
preferred
π .catch() handles:
rejection
thrown errors
entire chain
πΉ Recovery Pattern
Promise.reject("Error")
.catch((err) => {
console.log("Handled:", err);
return "Recovered";
})
.then((res) => {
console.log("Next:", res);
});
Output:
Handled: Error
Next: Recovered
πΉ When .catch() is Skipped
Promise.resolve("resolve")
.catch((err) => {
console.log(err);
})
.then((res) => {
console.log(res);
});
Output:
resolve
πΉ Transformation Chain
Promise.resolve(5)
.then((num) => num * 2)
.then((num) => num + 3)
.then(console.log);
Output:
13
πΉ Async Delay Example
function delay(val) {
return new Promise((resolve) => {
setTimeout(() => resolve(val), 1000);
});
}
delay(2)
.then((num) => num * 2)
.then((num) => delay(num + 3))
.then(console.log);
Output:
7
π§ Key Mental Models
1. Promise Flow
resolve β then β then β then
β
throw
β
catch
2. Return Flow
value β return β next then
no return β undefined β next then
3. Function Passing
.then(fn) β fn(value)
4. Promise Behavior
| Action | Result |
|---|---|
| resolve | then |
| reject | catch |
| throw | reject |
| no return | undefined |
π₯ Golden Rules
Always
returninside.then()if chaining.then()takes a function, not a valuethrowinside Promise = rejection.catch()handles everything downstreamPromises donβt block β they schedule execution