Introduction
A colleague of mine and I have been discussing the asynchronous nature of JavaScript in the browser and wondering what technical benefits are. We are aware that async/await is syntactical sugar for Promises, but curious to know if there is any other performance benefit for using one over the other. For example:
- Are both async/await and Promises treated the same by the event loop?
- Are they both considered microtasks?
- Is there any defered execution benefit from using one over the other (for example, code in a Promise executor is called synchronously, but what about in async functions)?
- According to MDN, an async function returns an
AsyncFunction
object, but there is no disussion of that under the Promise documentation – what benefits does theAsyncFunction
have? - Are the performance benefits the same (if there are any)?
Example Scenario
Are
await JSON.parse('json string');
and
new Promise((resolve, reject) => resolve(JSON.parse('json string')));
being treated the same way by the event loop (my syntax might be slightly off)?
References
- Understanding Asynchronous JavaScript – Sukhjinder Arora (13 Nov 2018)
- Tasks, microtasks, queues and schedules – Jake Archibald (17 Aug 2015)
- async function – MDN
- Promise – MDN
Advertisement
Answer
Are both async/await and Promises treated the same by the event loop?
The event loop is just handling events, I wouldn’t say that it treats things differently at all. Resolving a promise will cause an event to be pushed onto the loop, that then calls all .then
handlers on the next tick, as an async function also returns a promise and resolves it, you get the same behaviour.
Are they both considered microtasks?
The name “microtask” is used to explain the common behaviour of browsers, neither the spec nor NodeJS use it, so I would never state “xy is a microtask in JavaScript”. However if you call resolving a “microtask”, then returning from an async function is also a “microtask” as it resolves the underlying promise.
Is there any defered execution benefit from using one over the other (for example, code in a Promise executor is called synchronously, but what about in async functions)?
Code is always executed synchronously, asynchronity in JS means that external events (network requests, timers) reach the event queue somewhen, and therefore the code attached to it via callbacks gets called somewhen, however it then executes in a synchronous maner.
According to MDN, an async function returns an AsyncFunction object, but there is no disussion of that under the Promise documentation – what benefits does the AsyncFunction have?
No, it returns a promise, the async function
is itself an AsyncFunction Object, which just means that it is a FunctionObject with an internal value saying that its async.
const asyncFunctionObject = new AsyncFunction("return await stuff();"); async function functionObject() { return await stuff(); }
Are the performance benefits the same (if there are any)?
Maybe. That always depends on your exact usecase, so if you want to know it for sure test the performance. If you however look at these two examples:
// 1 a().then(() => b()).then(() => c()) // 2 (async function() { await a(); await b(); await c(); })();
then in the first case, if a, b and c are promises, there will be 5 promises (.then(...)
returns a new promise), while the second example only needs 4 (one returned by the async function). For loops the ratio will get even better.