JavaScript code by default operates synchronously, which can be pretty difficult for programmers who are already familiar with developing asynchronous applications. In this article, I will be discussing the various ways of writing Javascript code to operate asynchronously using callbacks and promises.
JavaScript runs on a single thread, and it can only do one thing at a time. In synchronous programming, if you have three lines of code (L1, L2, L3), then L3 can’t run before line L2 and L1 until L1 followed by L2 has finished executing. But in asynchronous programming, while Line 3 schedules some task to be run in the future, Line 2 and Line 1 can run concurrently before that task completes.
Asynchronous programming is very useful for JavaScript, as applications often make requests to servers elsewhere, and it can take a couple of seconds to get data back. During that time, you might want to keep other operations going. Asynchronous programming means that time- consuming operations don’t have to bring the entire program to a halt.
See examples below of synchronous operation using the setTimeout method.
Examples: Snippet 1
const food =[ {title: 'my number one favorite food', body: 'rice and spaghetti' }, {title: 'my number two favorite food', body: 'pasta' }, ]; function getFood(){ setTimeout(() => { let output = ''; food.forEach((item, index) => { output += `
After a second (1000 milliseconds), the Dom loads the two items listed; the food comes from the array and then it loops through and then displays them on the page with this line of code below:
{document.body.innerHTML = output;}
Output.
– my number one favorite food is rice and spagetti
– my number two favorite food is pasta
Snippet 2
function createFood(item){ setTimeout(() => { food.push(item); }, 2000); } createFood({title: 'my number three favorite food', body: 'fried chicken'}, getFood);
At this point, another function is created called createFood, taking in a new food item that I pass in the setTimeout method. The setTimeout () method calls the function after 2000 milliseconds because we are hypothetically dealing with a server. What do I want to happen? I want to get the food item and then create another one. After running the program, I got the same output as the first. See below.
– my number one favorite food is rice and spagetti
– my number two favorite food is pasta
Why did this occur? The reason is simple: because the createFood function took longer than the getFood function. The getFood happened in one second, the server returned it in one second. But by the time I ran the getFood, the Dom was already loaded, so nothing was possible beyond that point. Basically, this is where asynchronous programming via callbacks comes in, which is one of the ways to handle this. In order to allow for asynchronous operations, callbacks are required. Callbacks were not fully available until ES6 was released.
Callbacks:
Almost all web applications will make use of callbacks, either through events (e.g. window.onclick), setTimeout and setInterval, or AJAX requests.
function createFood(item, callback){ // callback function setTimeout(() => { food.push(item); callback(); }, 2000); } createFood({title: 'my number three favorite food', body: 'fried chicken'}, getFood);
Output
Now my third best food gets to show. There was a wait of two seconds, and all of the items appeared. There was a pause because there was a way to trigger createFood function before it actually called the “callback”; it had to push into it and then call the “call back.” So this is a good example of how callbacks work and why you would use a callback.
Promises
Promises in JavaScript are pretty much the same as making promises in reality (e.g., your kid promises to clean his room by the end of the day). He either fulfils his promise by cleaning the room or he fails. In JavaScript, promises are similar. See a simple example of promises below.
let promiseToCleanTheRoom = new Promise(function(resolve, reject) { // the function takes two arguements //cleaning the room let isClean = true; if (isClean) { resolve(' extremely clean'); } else { reject(' is quite dirty'); } }); promiseToCleanTheRoom.then(function(fromResolve) { console.log('The room is' + fromResolve); }).catch(function(fromReject){ console.log('the room is ' + fromReject); });
The .then method is called when a promise is resolved. When the promise is fulfilled, using “ .then,” it will pass the resolve argument, which is the same thing as fromResolved.
The console says the room is extremely clean — that is, the promise was resolved. if you have a lot of promises, you don’t want to keep using .then multiple times — Instead, use promise.all.
Tools for dealing with asynchronous code
If you are using lots of asynchronous functions, it can be worthwhile to use an asynchronous function library instead of creating your own utility functions. Async.js is a popular library that has many useful tools for dealing with asynchronous code.
Promises are a great way to get rid of callback hell. The idea is that instead of using functions that accept input and a callback, we make a function that returns a promise object — that is, an object representing a value that is intended to exist in the future.
Conclusion
This article gives a quick introduction to asynchronous JavaScript, with practical examples included so as to make it relatable to newbies. Asynchronous JavaScript and promises are broad subjects, and if you would like to use promises, I recommend you take an in-depth course.