JavaScript - Callbacks, Promises, and Async/Await

Hashan Bhanuka
4 min readMar 17, 2022

JavaScript is asynchronous. All I/O operations in JavaScript are implemented to be asynchronous by nature. The reason for this is JavaScript is a single-threaded language if an I/O operation holds the thread till it gets completed JavaScript won’t perform well as a programming language. But asynchronous operation introduces difficulty when we need to do synchronous processing using data. To solve this problem, JavaScript provides three methods: callbacks, promises, and async/await.

Callback function

A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.

Here is a quick example:

The example above is a synchronous callback as it is executed immediately. However, callbacks are often used to resume code execution after an asynchronous operation has been completed. these are referred to as asynchronous callbacks.

But the problem with callbacks is that it creates something called “Callback Hell”. Basically, you start nesting functions within functions within functions and it becomes really difficult to read the code.

Let’s see an example:

See above code So in this situation Promises came to handle the nested callback in a better way.

Promises

Promises are one of the best additions to JavaScript because they make handling async code so much easier. Going from callbacks to promises feels like a massive upgrade.

Promises have three states:

  • Pending - This is the initial state of a Promise.
  • Fulfilled - The state of a promise representing a successful operation.
  • Rejected - The state of a promise representing a failed operation and error value is usually thrown.

Create a Promise
When creating a Promise object, it takes a function with two parameters: resolve and reject. Resolve and Reject are functions. The resolve function is the success function and should be called whenever the promise succeeded. The reject function is the error function and should be called whenever the promise could not be completed successfully.

Let’s see a promise example:

In the above Promise when the randomly generated number is 2, resolve the promise and return “You guessed correctly”, else reject the promise and return “wrong number”.

Using Promise

To use create promise we use .then() for resolve the promise and .catch() function use to reject the promise.

Async and Await

Async/await is an alternative syntax for promises that makes reading/writing asynchronous code even easier.

An async function is a function declared with the async keyword, and async functionalways returns a promise. The async and await keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains.

The await operator is used to waits till promise is settled. It can only be used inside an async function within regular JavaScript code.

Here is an example for async/ await :

In this example, the getData function waits for the resolved promise returned by the guessedValue function. If the promise is rejected here, it handles with try and catch.

Conclusion

async/await is a cleaner way of handling promises instead of doing the .then and all that stuff, and it’s also cleaner than callbacks.

--

--