Skip to content

Instantly share code, notes, and snippets.

@swashata
Created March 5, 2021 12:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swashata/299cba7f0943ee2051ba01db7ef2879a to your computer and use it in GitHub Desktop.
Save swashata/299cba7f0943ee2051ba01db7ef2879a to your computer and use it in GitHub Desktop.
Callbacks and Promises in JS with nesting
// 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.
// 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