Callback, async-await, Promises

Callback, async-await, Promises

ยท

4 min read

Prerequisites: Basic programming in JavaScript (variables, loops, functions)

While learning JavaScript(JS) I was particularly looking forward to learning the asynchronous(async) nature of JavaScript that everyone talks about and is scared of!

So let's get into it because we don't let fear stop us๐Ÿ’ช

A quick intro to callback functions before jumping to async functions.

Callback functions

Callback functions: A function passed as a parameter to another function.

It is as simple as that, don't overthink this. Take a quick look at this example


function squareOf(n){
    return n*n;
}

function sumOfSqaures(a, b, callbackFn){
    let result = callbackFn(a) + callbackFn(b);
    return result;
}

console.log("\nSum of squares of 1 and 2 : " + sumOfSqaures(1,2,squareOf));

Copy and try this code out here if you don't have node installed on your system: Replit

Output :

There are different styles of calling a callback function when calling the actual function, so make yourself familiar with it to not get confused like me:

Defining the function while passing it as a parameter: (This is called an Anonymous function)

function sumOfSqaures(a,b,callbackFn){
    return callbackFn(a) + callbackFn(b);
}

console.log(sumOfSqaures(1,3,function(n){
    return n*n;
}));

As an arrow function ( basically removing the word function)

function sumOfSqaures(a,b,callbackFn){
    return callbackFn(a) + callbackFn(b);
}

console.log(sumOfSqaures(1,3,(n) =>{ return n*n; }));

The above two are just the simplified versions so don't get overwhelmed.

Yet! :)

Now onto the Async nature of JS ->

What in the Asynchronous ?!

Firstly, the important thing to understand is that JS is single-threaded. Which means it can only perform one task at any given point in time. Engines that interpret JS (Ex: V8) flow this way: imagine these interpreters have only one hand and therefore can perform only one thing at a time. But with this approach, it will take a lot of time to complete complex tasks.

To avoid waiting for one task to complete, the interpreter DELEGATES the task to someone(we will see who that is) and moves on to the next task. It asks "someone" to complete the task and asks it to return the result, till then it moves on in the code.

Understand below flow:

Now let's understand what that someone is who gets assigned these time-taking tasks. It is the web APIs (on browser) or Environment that handles it.

There are different places where different functions are stored in stack/queue while executing the code.

Let's see what goes where.

Here's a simplified overview of how the event loop works:

  1. Call Stack: Where JS keeps track of function calls.

  2. Web APIs/Environment: Browser or Node.js APIs handle asynchronous operations (e.g., setTimeout, HTTP requests).

  3. Callback Queue: Functions to be executed after asynchronous operations are complete.

  4. Event Loop: Continuously checks the call stack and the callback queue, pushing functions from the callback queue to the call stack when the stack is empty.

To better visualize and understand the working of event loops, use this tool: Latent-Flip. Try different async code snippets here. Trust me this will make your life easier!! ๐Ÿค

Now that we know the asynchronous nature of JS, let's get into async-await syntax, and promises.

Normally we as developers won't have to define a lot of async functions but rather learn to use predefined JS functions.

Async keyword is used to make a function return a promise!

WHAT? PROMISE?

As the word suggests a promise is an object that promises to return the success or failure of a task that will take time. Hence we use promise to make sure that the time-taking task "promises" to return. An async task always keeps its promise (unlike your ex๐Ÿ™Œ).

A promise resolves or rejects.

Await is like a pause button. When you use await before a promise, it tells JavaScript to wait until the promise is fulfilled before moving on.

If you have defined an async function, you have to use the await keyword inside. This was introduced only to make the code look pretty. It makes it look like the synchronous style of code.

Let's understand with an example:

Task is to order pizza but because it will take time, you place the order and move on to do your thing.

// This is a function that returns a promise (ordering a pizza)
function orderPizza() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            let success = true; // Change this to false to see what happens when it fails
            if (success) {
                resolve("Pizza has arrived!");
            } else {
                reject("Pizza failed to arrive.");
            }
        }, 2000); // Pizza arrives in 2 seconds
    });
}

// This is an async function where we wait for the pizza
async function waitForPizza() {
    try {
        console.log("Ordering pizza...");
        const result = await orderPizza(); // Wait for the pizza to arrive
        console.log(result); // Pizza has arrived!
    } catch (error) {
        console.error(error); // Handle the error if pizza fails to arrive
    }
}

waitForPizza();

That's all.

Yes, this is overwhelming and you might not get this in the first go like me! THAT'S OK! You will be fine if you keep on writing code in JS, you will get used to its scary asynchronous nature lol.

Hope this was helpful!

Feel free to reach out to me : Linktree

ย