Created
March 5, 2021 12:45
-
-
Save swashata/299cba7f0943ee2051ba01db7ef2879a to your computer and use it in GitHub Desktop.
Callbacks and Promises in JS with nesting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Below are some sample functions which take a callback and does some async action | |
// When the action is successful, it will call the callback with the data | |
function fetchPosts(callback) { | |
// somehow we get our posts | |
const posts = [ | |
'Awesome Posts', | |
'Another one', | |
]; | |
// call the callback with posts | |
callback(posts); | |
} | |
function fetchTasks(callback) { | |
// somehow we get our tasks | |
const tasks = [ | |
'Task one', | |
'Task two', | |
]; | |
// call the callback with tasks | |
callback(tasks); | |
} | |
// dealing with one callback is fairly straight forward | |
fetchTasks(tasks => { | |
// do something with tasks | |
console.log(tasks); | |
}); | |
// What if we want both posts and tasks in a single function? | |
// we nest callbacks | |
fetchTasks(tasks => { | |
fetchPosts(posts => { | |
// here we have access to both tasks and posts, because the callback to fetchPosts | |
// is a closure inside the callback to fetchTasks | |
console.log(tasks, posts); | |
}); | |
}); | |
// While this callback nesting works good, it can become a callback hell very fast. | |
fetchSomething(dataOne => { | |
fetchSomethingElse(dataTwo => { | |
fetchSomethingMore(dataThree => { | |
fetchAgain(dataFour => { | |
// you get the point | |
console.log(dataOne, dataTwo, dataThree, dataFour); | |
}); | |
}); | |
}); | |
}); | |
// and we have a better way to do this, it's called promises. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Below are some sample functions that return a promise which would resolve into some data | |
function fetchPosts() { | |
// somehow we get our posts | |
const posts = [ | |
'Awesome Posts', | |
'Another one', | |
]; | |
// return a promise which would resolve into some data | |
return new Promise((resolve) => { | |
resolve(posts); | |
}); | |
} | |
function fetchTasks() { | |
// somehow we get our tasks | |
const tasks = [ | |
'Task one', | |
'Task two', | |
]; | |
// return a promise which would resolve into some data | |
return new Promise((resolve) => { | |
resolve(tasks); | |
}); | |
} | |
// Now geting and handling both the data is very straight forward. | |
// We can do one by one | |
fetchPosts().then(posts => { | |
fetchTasks().then(tasks => { | |
console.log(posts, tasks); | |
}); | |
}); | |
// But the above still looks like callback hell, so we can refactor using async function | |
async function handlePostsAndTasks() { | |
const tasks = await fetchTasks(); | |
const posts = await fetchPosts(); | |
console.log(posts, tasks); | |
} | |
handlePostsAndTasks(); | |
// Or we can use Promise.all to simultaneously get posts and tasks | |
Promise.all([fetchPosts(), fetchTasks()]).then(([posts, tasks]) => { | |
console.log(posts, tasks); | |
}); | |
// Async+Await way of writing the above would be | |
async function simultaneuosPostsAndTasks() { | |
const [posts, tasks] = await Promise.all([fetchPosts(), fetchTasks()]); | |
console.log(posts, tasks); | |
} | |
simultaneuosPostsAndTasks(); | |
// IMPORTANT | |
// When dealing with promises, make sure you | |
// 1. Use .catch in promise .then chain | |
// 2. Use try...catch for async+await | |
// Learn here | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise | |
// https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment