Thought leadership from the most innovative tech companies, all in one place.

Callback vs Promise and Async/Await in JavaScript

A callback function is a function passed into another function as an argument, which is called (or executed) inside the otherFunction. So the basic way to handle asynchronous operations is through…

Callback vs Promise and Async/Await

Callback function

A callback function is a function passed into another function as an argument, which is called (or executed) inside the otherFunction. Example: callback

Example: callback

So the basic way to handle asynchronous operations is through callbacks. But when working with a lot of dependent asynchronous operations, you quickly end up in callback hell.


The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value. Essentially, a promise is a returned object to which you attach callbacks, instead of passing callbacks into a function. Example: Promise

Example: Promise

A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action’s eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future. Promise-concept


Some of the following options are available with Promise. 1.Promise.all The Promise.all(iterable) method returns a single Promise that resolves when all of the promises in the iterable argument have resolved or when the iterable argument contains no promises. It rejects with the reason of the first promise that rejects. Example: Promise.all

Example: Promise.all

2.Promise.race The Promise.race(iterable) method returns a promise that resolves or rejects as soon as one of the promises in the iterable resolves or rejects, with the value or reason from that promise. Example: Promise.race

Example: Promise.race

Async & Await

The async function declaration defines an asynchronous function, which returns an AsyncFunction object. Async/await is actually built on top of promises. It cannot be used with plain callbacks or node callbacks. The word “async” before a function means one simple thing: a function always returns a promise. If the code has return in it, then JavaScript automatically wraps it into a resolved promise with that value. The keyword await makes JavaScript wait until that promise settles and returns its result. Example: Async/Await

Example: Async/Await

Which Approach Should we Use? We have the following options to handle async things in JavaScript.

  • Callback
  • Promise
  • async/await
  • RxJS Observables Use Callbacks if you got no other choice or only handle one async operation. The code will then still be perfectly manageable and understandable. Callback functions aren’t bad per se — there just exist better alternatives in many cases. One such case is multiple chained (or dependent) asynchronous operations. You quickly enter callback hell when trying to use callbacks in such a situation. Promises are a great tool to handle your operations in a structured and predictable way. async/ await is an awesome tool for cases where you don’t really want or need to use observables but still want to use promises. You can write “synchronous” code with async/ await and handle your promise chains even easier. In all cases where you use promises, you might also use observables. But RxJS is something third-party library to handle async operation on the data stream.


1.Callbacks with the danger of entering callback hell 2.Promises to escape callback hell 3.async/ await to write “synchronous” code with promises 4.Observables to handle streams of data and apply operator magic Please find all example source code on the following gist.

Continue Learning