Practical difference between async await and callback

In one of our tutorial, we learned how to create a function in async await and how to create a function that uses callback.

Video tutorial:

Asynchronous

Let’s say you want to send an email to a user. Following is a Node JS code that sends an email using a callback:

const transport = nodemailer.createTransport({
	host: "",
	port: 465,
	secure: true,
	auth: {
		user: "",
		pass: ""
	}
})

transport.sendMail({
	from: "support@adnan-tech.com",
	to: "",
	subject: "Test",
	text: "Hello",
	html: "Hello"
}, function (error, info) {
	console.log("Mail sent: " + (new Date()))
})

console.log("I am called: " + (new Date()))

In your terminal, you will see that the “I am called:” message will be displayed instantly. But the “Mail sent:” message will be shown after a few seconds, once the mail is sent. It means that all lines of your code are executed at once, irrespective of the fact that the sendMail function will take some. The code is executed without waiting for any function to complete. This is asynchronous programming.

Synchronous

This can be converted into a synchronous function. Following is the synchronous version of the above code:

// the function must be async if await is used inside it

app.get("/sendMail", async function (request, result) {

	// send an email using a callback
	const transport = nodemailer.createTransport({
		host: "",
		port: 465,
		secure: true,
		auth: {
			user: "",
			pass: ""
		}
	})

	const info = await transport.sendMail({
		from: "support@adnan-tech.com",
		to: "",
		subject: "Test",
		text: "Hello",
		html: "Hello"
	})

	console.log("Mail sent: " + (new Date()))

	console.log("I am called: " + (new Date()))

	result.send("")
})

If you run the code now, you will have to wait for the sendMail function to finish before you see your log messages. This is synchronous programming.

Now you have understood the difference, let’s discuss where you should use async await and where you should use a callback.

When to use async await

You should use the async await pattern when the next line of your code is dependent on the previous lines. For example, “you have to insert the record in the database only if the mail is sent successfully”. In this case, you must use async await so that your code will wait for the mail to be sent successfully, then it will insert it in the database.

When to use callback

A callback will be helpful when your code sections are independent of each other. For example, “send an email to the user and insert the record in the database.” In this case, your insertion query should not have to wait for the mail to be sent. The mail should be handled in a callback.

Promise and async await in Javascript

Promises are created in Javascript to prevent the callback hell. But it came with its own problems and complexities. To deal with them, we were introduced to async and await commands. So today, we are going to teach you, how you can create a promise in Javascript, and how to call it using async/await command.

Video tutorial

Basic example of promise with async await

Let’s start with a basic example. We are going to create a simple Javascript function that will return a promise. The promise will call the callback function with a string value.

function doSomething() {
	return new Promise(function (callBack) {
		callBack("Response")
	})
}

To use the async and await commands, we need to create another function that will use these commands.

async function callDoSomething() {
	const response = await doSomething()
	console.log(response)
}

The function name will be prepended with async and the function that returns a promise i.e. doSomething() will be prepended with await command. In this case, the response variable should print “Response” that was called at line 3 of previous code.

Finally, we simply need to call the callDoSomething() to run the code.

callDoSomething()

Run the code now, and you will see “Response” in your browser console. Try change the string value of callBack parameter and you will see that it will be reflected in response variable in callDoSomething() function.

Practical example

Let’s move to a more practical example. Let’s say you want to call an AJAX request from the promise. And instead of receiving the response in a callback, you want to receive it using async/await command.

So go ahead and change the doSomething() function to the following:

function doSomething() {
	return new Promise(function (callBack) {
		const ajax = new XMLHttpRequest()
		ajax.open("POST", "server.php", true)

		ajax.onreadystatechange = function () {
			if (this.readyState == 4) {
				if (this.status == 200) {
					callBack(this.responseText)
				}
			}
		}

		const formData = new FormData()
		ajax.send(formData)
	})
}

The code is self-explanatory but if you want to know more about the XMLHttpRequest, we have created a separate detailed tutorial on this.

Then we will create a simple PHP file that will return a simple string as response. Create a new file named server.php and write the following code in it:

<?php

sleep(1);

echo "Response from server";
exit();

We are calling the sleep() function just to give it 1 second delay. If you run the code now, you will start seeing “Response from server” in the browser console.

[wpdm_package id=’1720′]