Skip to content
Advertisement

Are javascript’s async functions actually synchronous?

I am trying to figure out how does asynchronous code work in Javascript. Now, I understand that there is actually one single thread in JS that executes jobs in a queue, and it can only start executing the next job if the current one is completed (i.e. if all of the sync code or an async function is completed).

Now, the confusing part is what actually counts as an asynchronous function – what actually gets put into a separate job in the queue, and what doesn’t.

For start, we have the async keyword for functions. So does that mean those functions will be put into a separate job in the queue and be executed somewhere in the future? Well, actually it turns out the answer is NO. But bear with me, as I will explain.

As far as I understand, in theory, the JS thread is supposed to begin by executing all synchronous code until it completes, while delaying the execution of all async functions, promises and callbacks by placing them as jobs to the end of the queue. Then, once all sync code completes, it will start doing all those jobs that got piled up.

So if I have the following code:

JavaScript

Then in theory, it should execute all sync code first, and only then start executing the async function and then the callback:

JavaScript

But the reality is different! In reality, it actually executes the async function synchronously, together with the rest of the sync code. The only bit that actually gets put into the job queue is the callback of the async function:

JavaScript

So what does that mean? That async functions are actually a lie? It seems so, as they are actually normal, synchronous functions that you can happen to attach an async callback to.

Now, I know that async is actually a syntactic sugar for a function that returns a Promise, such as:

JavaScript

is syntactic sugar for:

JavaScript

But my point still remains. The supposedly-async function that you pass into the promise actually is executed synchronously. Well, technically the Promise object doesn’t imply that it will be executed asynchronously, but the async keyword does! So it’s outright false information, it makes you believe that it’s asynchronous, when it demonstrably isn’t.

Advertisement

Answer

Just like when constructing a Promise, anything synchronous inside an async function before any awaits are encountered will execute synchronously. An async function will only stop executing its code once it encounters an await – until then, it may as well be a normal non-async function (except for the fact that it’ll wrap the return value in a Promise).

JavaScript

As you can see in the snippet above, the main thread only resumes outside of asyncFunc1 once asyncFunc1‘s await (and all synchronous code invoked by that await) is complete.

async is a keyword that allows you to use await inside of a function, but it doesn’t intrinsically mean anything else, really – it’s just a keyword. The function may even run all of its code synchronously (though that’d be kind of weird to see).

Advertisement