DEV Community

loading...

Asynchronous Javascript: Callbacks and Promises

dianakw8591
Rock climber turned coder.
・2 min read

As the Javascript module of Flatiron's Software Engineering immersive wraps up, one thing has become quite clear: I really need to understand callbacks and asynchronous functions to understand how to effectively use Javascript. Below, I've laid out my understanding of callbacks and how promises make asynchronous Javascript easier to user and understand.

First, we have to understand that Javascript is a synchronous, blocked language where functions only execute after the previous function has finished. But there are also functions available that are asynchronous, fetch and event handlers for example. Other code will continue to execute while the asynchronous function is waiting to complete, perhaps waiting for response from a server.

Callbacks can be used in both synchronous and asynchronous Javascript, but often are used in asynchronous ways. Callbacks are functions passed to another function that are called after that function completes. An example of a synchronous callback could be this simple:

function funcA(num) {
    return num * 2
}

function funcB(cb) {
    return cb(5)
}

funcB(funcA)
//10

It's just passing a function to another function, in this case, funcA to funcB. But that's not very interesting.

Callbacks used in asynchronous code result in something called "callback hell" which I recommend googling. Basically, something like this:

asyncAction1((res1, err) => {
  if (err) { handle() }
  asyncAction2((res2, err) => {
      if (err) { handle() }
    asyncAction3((res3, err) => {
      if (err) { handle() }
      // do something
    });
  });
});

It's messy to look at unpleasant to deal with. Promises help to fix this mess by returning a Promise object that is a proxy for an actual value. It's the promise to return that value, and is either pending, fulfilled, or rejected. .then can be called on promise and whatever work is done in the .then block will only be run after the promise has been resolved. Similarly, .catch will handle errors if the promise is rejected.

So to rewrite the code above with promises:

asyncAction1
.then((res1) => asyncAction2(res1))
.then((res2) => asyncAction3(res2))
.then((res3) => functionThatDoesSomething(res3))
.catch(err)

I hear async/await is even cleaner and nicer to use for a variety of reasons, but that part is for another post! Thanks for reading!

Discussion (0)