Dealing with asynchronous code, meaning code that doesn’t execute immediately like web requests or timers, can be tricky. JavaScript gives us two ways out of the box to handle asynchronous behavior: callbacks and promises.
Callbacks were the only natively supported way for dealing with async code until 2016, when the Promise
object was introduced to the language. However, JavaScript developers had been implementing similar functionality on their own years before promises arrived on the scene. Let’s take a look at some of the differences between callbacks and promises, and see how we deal with coordinating multiple promises.
Asynchronous functions that use callbacks take a function as a parameter, which will be called once the work completes. If you’ve used something like setTimeout
in the browser, you’ve used callbacks.
// You can define your callback separately...
let myCallback = () => {
console.log('Called!');
};
setTimeout(myCallback, 3000);
// … but it’s also common to see callbacks defined inline
setTimeout(() => {
console.log('Called!');
}, 3000);
Usually the function that takes a callback takes it as its last argument. This is not the case above, so let’s pretend there’s a new function called wait
that is just like setTimeout
but takes the first two arguments in opposite order: