Is using async
and await
the crude person's threads?
Many moons ago I learned how to do multithreaded Java code on Android. I recall I had to create threads, start threads, etc.
Now I'm learning Javascript, and I just learned about async
and await
.
For example:
async function isThisLikeTwoThreads() {
const a = slowFunction();
const b = fastFunction();
console.log(await a, await b);
}
This looks way simpler than what I used to do and is a lot more intuitive.
slowFunction()
would start first, then fastFunction()
would start, and console.log()
would wait until both functions resolved before logging - and slowFunction()
and fastFunction()
are potentially running at the same time. I expect it's ultimatly on the browser whether or not thesea are seperate threads. But it looks like it walks and talks like crude multithreading. Is it?
Async programming is about non-blocking execution between functions, and we can apply async with single-threaded or multithreaded programming. So, multithreading is one form of asynchronous programming.
Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. You can use Task.
Multithreading in JavaScript is the real right now. You can offload your work into multiple threads and share memory between them.
Myth 1: Promises Enable Multi-Threaded JavaScript JavaScript runtime is strictly single-threaded, but you have to remember that the JavaScript runtime is only one system (or “Thread”) in a browser or Node.
Multithreading Async and Await API – Asynchronous Programming Asynchronous programming is an important programming technique that lets you perform multiple tasks at a time thereby increasing the throughput of your Application, API, Services or Method, etc. In this article we shall cover below, Synchronous API execution and example
No asynchronous programming doesn't mean multithreading specifically. For achieving multiple tasks at the same time we use multi-threading and other is event loop architecture in node js. JavaScript is synchronous and single threaded and that is why node js is also single threaded but with event loop node do a non-blocking I/O operations.
So, async ensures that the function returns a promise, and wraps non-promises in it. Simple enough, right? But not only that. There’s another keyword, await, that works only inside async functions, and it’s pretty cool. The keyword await makes JavaScript wait until that promise settles and returns its result.
JavaScript is synchronous and single threaded and that is why node js is also single threaded but with event loop node do a non-blocking I/O operations. Node.js uses the libuv library that uses a fixed-sized thread pool that handles the execution of parallel tasks. Thread is a sequence of code instructions and also the sub unit of process.
Is using
async
andawait
the crude person's threads?
No, not at all. It's just syntax sugar (really, really useful sugar) over using promises, which in turn is just a (really, really useful) formalized way to use callbacks. It's useful because you can wait asynchronously (without blocking the JavaScript main thread) for things that are, by nature, asynchronous (like HTTP requests).
If you need to use threads, use web workers, Node.js worker threads, or whatever multi-threading your environment provides. Per specification (nowadays), only a single thread at a time is allowed to work within a given JavaScript "realm" (very loosely: the global environment your code is running in and its associated objects, etc.) and so only a single thread at a time has access to the variables and such within that realm, but threads can cooperate via messaging (including transferring objects between them without making copies) and shared memory.
For example:
async function isThisLikeTwoThreads() { const a = slowFunction(); const b = fastFunction(); console.log(await a, await b); }
Here's what that code does when isThisLikeTwoThreads
is called:
slowFunction
is called synchronously and its return value is assigned to a
.fastFunction
is called synchronously and its return value is assigned to b
.isThisLikeTwoThreads
reaches await a
, it wraps a
in a promise (as though you did Promise.resolve(a)
) and returns a new promise (not that same one). Let's call the promise wrapped around a
"aPromise
" and the promise returned by the function "functionPromise
".aPromise
settles, if it was rejected functionPromise
is rejected with the same rejection reason and the following steps are skipped; if it was fulfilled, the next step is doneisThisLikeTwoThreads
continues by wrapping b
in a promise (bPromise
) and waiting for that to settlebPromise
settles, if it was rejected functionPromise
is rejected with the same rejection reason; if it was fulfilled, the code in isThisLikeTwoThreads
continues by logging the fulfillment values of aPromise
and bPromise
and then fulfilling functionPromise
with the value undefined
All of the work above was done on the JavaScript thread where the call to isThisLikeTwoThreads
was done, but it was spread out across multiple "jobs" (JavaScript terminology; the HTML spec calls them "tasks" and specifies a fair bit of detail for how they're handled on browsers). If slowFunction
or fastFunction
started an asynchronous process and returned a promise for that, that asynchronous process (for instance, an HTTP call the browser does) may have continued in parallel with the JavaScript thread while the JavaScript thread was doing other stuff or (if it was also JavaScript code on the main thread) may have competed for other work on the JavaScript thread (competed by adding jobs to the job queue and the thread processing them in a loop).
But using promises doesn't add threading. :-)
I suggest you read this to understand that the answer is no: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
To summarize, the runtime uses multiple threads for internal operations (network, disk... for a Node.js environment, rendering, indexedDB, network... for a browser environment) but the JavaScript code you wrote and the one you imported from different libraries will always execute in a single thread. Asynchronous operations will trigger callbacks which will be queued and executed one by one.
Basically what happens when executing this function:
async function isThisLikeTwoThreads() {
const a = slowFunction();
const b = fastFunction();
console.log(await a, await b);
}
Execute slowFunction
.
Execute fastFunction
.
Enqueue the rest of the code (console.log(await a, await b)
) when a
promise and b
promise have resolved. The console.log
runs in the same thread after isThisLikeTwoThreads
has returned, and after the possible enqueued callbacks have returned. Assuming slowFunction
and fastFunction
both return promises, this is an equivalent of:
function isThisLikeTwoThreads() {
const a = slowFunction();
const b = fastFunction();
a.then(aResult => b.then(bResult => console.log(aResult, bResult)));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With