Asynchronous programming ensures a long-running task maintains responsiveness to other events even as the task goes on. It's a form of programming that caters to functions requiring time to deliver requests to the end-users. This ensures multiple tasks and functions can run with little downtime or long wait times.
Asynchronous means "not occurring at the same time," and it applies in real life, for example, in remote jobs.
Some jobs state that they work with asynchronous communication, meaning teams don't work simultaneously and can choose different schedules and timelines.
The opposite of Asynchronous programming is synchronous programming. Synchronous means events or activities occurring at the same time. For example, remote classes that occur at the same time, regardless of time zones, or a typical 9-5 work schedule where all employees work at the same time with no flexibility.
**In JavaScript, synchronous programming means that the next line of code cannot run until the first one runs entirely. **
For example, when you console.log the statements below, synchronous JavaScript executes them in the order that you wrote the code:
console.log("i")
console.log("am")
console.log("a")
console.log("Frontend")
console.log("Developer");
The result is:
"i"
"am"
"a"
"Frontend"
"Developer"
Asynchronous JavaScript
In Asynchronous programming, functions are like people working remotely and with flexible schedules. People execute different tasks at different intervals, all while other activities are still going on without affecting the overall goals of a team or the company.
Why is an Asynchronous state necessary? For starters, you cannot control how different users interact with your programs. Your only option is to create an environment where programs can run simultaneously without negatively affecting the functionality and user experience.
Real-life application of Asynchronous JavaScript:
Making requests to servers - it can take some time to get your data requests so Asynchronous JS keeps your program running while you wait to receive a response from the server.
Enhancing application responsiveness– most applications rely on asynchronous because it can be time consuming to run single threads that wait for single tasks to run before running the next ones.
Asynchronous JavaScript allows you to break down large code blocks into smaller tasks that are easier to manipulate.
Let’s use an example of breaking down larger code blocks into smaller ones with the setTimeout function. Asynchronous sets aside the setTimeout function while the system runs the other console.log requests, then it runs the setTimeout after the 5 seconds elapse.
console.log ("i"),
console.log ("am"),
console.log ("a"),
setTimeout (()=>{
console.log("Frontend")
}, 5000)
console.log("Developer")
The output:
"i"
"am"
"a"
"Developer"
"Frontend"
There are three core concepts in Asynchronous JavaScript that you need to know:
Callbacks
Async/ Await
Promises
Callbacks
Callbacks "call" or nest a function within another function to be used at a later time. Callbacks are a great way of invoking and connecting multiple functions to complete a task. We'll use an example of cooking food. To do this, you need to lay out a plan and execute each step to serve your meal. A likely step-by-step scenario is:
1. create the recipe 2. get the ingredients 3. preparation 4. cook the meal 5. serve
Let’s create two functions: the recipe as first function and preparation as second function. Inside the recipe function, we’ll print the message “I created the recipe” and in the preparation function, we’ll print “Ingredients bought, cook and server as per the recipe”.
Next, We’ll use a callback to form a relationship between the two functions.
To do this we need to pass the (get_ingredients) argument into the first function and invoke the argument within the same function as a callback.
Every time you create the recipe, you will get the ingredients (i.e., pass the "get_ingredients" argument) to the procedure which is the . This is what a callback does. Finally, call both functions with by calling both functions. See the demo below:
//Callbacks
let recipe = (get_ingredients) =>{
console.log("I created the recipe")
get_ingredients ()
};
let preparation = () => {
console.log("Ingredients bought, cook and serve as per the recipe")
};
recipe(preparation);
The output:
"I created the recipe"
"Ingredients bought, cook and server as per the recipe"
Async/Await
This is a newer way of writing Asynchronous JavaScript and a simpler way of writing promises. Async syntax uses the async keyword and can be placed before a function like the below:
async function f() { return “hello world”; }
When async is used before a function, the keyword returns a promise and also wraps non-promises.
Await syntax:
let value = await promises
The await keyword ensures JavaScript waits till a promise is settled and returns a result.
Promises
Promise, as the name suggests, represents a future state of operation that's not yet completed. It's also referred to as a proxy for the value realized later. With the food example, we are "promising" to serve a meal. Promises have four states:
1. Pending 2. fulfilled 3. Settled 4. Rejected
Promises were created to escape a phenomenon called “callback hell” due to the numerous function nesting you’d have to do to functions to get a result.
Async/Await is the default way to write simpler promises, and async is the keyword used. When async is used before a function, the keyword returns a promise and also wraps non-promises. The syntax looks like this:
async function f() {
return “hello world”;
}
A typical promise function looks like:
function items( ){
return new Promise( (resolve, reject) =>{
// write your code here
} )
}
But with async/await, the function above will look like this:
async function items(){
//write your code here
}
Another distinction between promises and async/await is that promises use resolve and reject keywords to pass our arguments. However, in async/await, we use the try and catch keywords to catch errors. See the code example:
Await Keyword - the await keyword ensures JavaScript waits till a promise is settled and returns a result. Await syntax:
let value = await promises* *
Recap
In the article above, you've learned asynchronous JavaScript and the main concepts: callbacks, Async/Await, and promises. You've also learned about callback hell and why JavaScript evolved this concept into promises, which is an easier way to define nested functions.