Reputation: 339
I went through the link below and understood single threaded javascript and its asynchronous nature a little
https://www.sohamkamani.com/blog/2016/03/14/wrapping-your-head-around-async-programming/
But I still have questions that javascript is single threaded and it always moves in forward direction in sequential manner until it finishes its execution.
Whenever we made call to function which has a callback, that callback will be executed after function receives response. Execution of javascript code continues during the wait time for the response. In this way where execution happening in sequence how callback execution will be resumed once after response received. It's like thread is moving backwards for callback execution.
Thread of execution should always move in forward direction righy?.
please clarify on this.
Upvotes: 17
Views: 12795
Reputation: 113
JavaScript is a single-threaded language. This represents it only has one thread to execute all tasks.
In synchronous - executes line by line and blocks further execution until each line has finished processing JS engine executes our program sequentially, particularly with blocking operations.
In asynchronous - where multiple tasks can be executed together without waiting for each other. This allows non-blocking operations. Typically use callbacks, promises, or async/await syntax to handle the completion of the I/O operation via the callback queue and event loop.
Note:- "In single-threaded programming, tasks are executed synchronously" - no, not necessarily.
Upvotes: -1
Reputation: 1
When you call an async function, it starts executing immediately. However, if the function encounters an await keyword, it doesn't block the execution of the whole program. Instead, the function may initiate specific tasks and pauses the execution of the async function itself and allows the main thread to continue executing other code. The async function is essentially "suspended" at that point.
While the async function is suspended, the initiated task may perform some long-running operation, such as making a network request or reading a file. These operations are typically handled by non-JavaScript parts of the environment, such as the browser or the Node.js runtime, which have separate threads to handle I/O operations.
Under the hood, JavaScript operates within a single-threaded event loop model, where the main thread handles most tasks. However, this model integrates asynchronous operations like network requests and file reads by employing additional threads from the environment (such as browser or Node.js).
async functions can delegate certain tasks, such as network requests, to separate threads managed by the runtime environment. These threads, distinct from the main JavaScript thread, handle the I/O-bound operations efficiently. Once the delegated task completes, a callback is added to the event loop's queue. The async function, upon being unblocked, processes this callback, enabling it to resume execution with the result of the task.
Upvotes: 0
Reputation: 1073978
It's true that JavaScript is (now) specified to have only a single active thread per realm (roughly: a global environment and its contents).¹ But I wouldn't call it "single-threaded;" you can have multiple threads via workers. They do not share a common global environment, which makes it dramatically easier to reason about code and not worry about the values of variables changing out from under you unexpectedly, but they can communicate via messaging and even access shared memory (with all the complications that brings, including the values of shared memory slots changing out from under you unexpectedly).
But running on a single thread and having asynchronous callbacks are not at all in conflict. A JavaScript thread works on the basis of a job queue that jobs get added to. A job is a unit of code that runs to completion (no other code in the realm can run until it does). When that unit of code is done running to completion, the thread picks up the next job from the queue and runs that. One job cannot interrupt another job. Jobs running on the main thread (the UI thread in browsers) cannot be suspended in the middle (mostly²), though jobs on worker threads can be (via Atomics.wait
). If a job is suspended, no other job in the realm will run until that job is resumed and completed.
So for instance, consider:
console.log("one");
setTimeout(function() {
console.log("three");
}, 10);
console.log("two");
When you run that, you see
one two three
in the console. Here's what happened:
console.log
, setTimeout
, and last console.log
setTimeout
callback to run and added a job to the job queue to run itconsole.log
If the main JavaScript thread were tied up (for instance, while (true);
), jobs would just pile up in the queue and never get processed, because that job never completes.
¹ The JavaScript specification was silent on the topic of threading until fairly recently. Browsers and Node.js used a single-active-thread-per-realm model (mostly), but some much less common environments didn't. I vaguely recall an early fork of V8 (the JavaScript engine in Chromium-based browsers and Node.js) that added multiple threading, but it never went anywhere. The Java virtual machine can run JavaScript code via its scripting support, and that code is multi-threaded (or at least it was with the Rhino engine; I have no ideal whether Narwhal changes that), but again that's quite niche.
² "A job is a unit of code that runs to completion." and "Jobs running on th emain thread...cannot be suspended in the middle..." Two caveats here:
alert
, confirm
, and prompt
— those 90's synchronous user interactions — suspend a job on the main UI thread while waiting on the user. This is antiquated behavior that's grandfathered in (and is being at least partially phased out).
Naturally, the host process — browser, etc. — can terminate the entire environment a job is running in while the job is running. For instance, when a web page becomes "unresponsive," the browser can kill it. But that's not just the job, it's the entire environment the job was running in.
Upvotes: 50
Reputation: 1554
Just to add to T.J.Crowder’s answer above:
The job queue is called an Event Loop which keeps track of all the callbacks that need to be executed. Whenever a callback is ready to be executed ( example: after an asynchronous action has finished ), it is added in the Event loop.
As explained by T.J. Crowder, you can imagine Event loop as a queue. Whenever there is a callback to execute in the loop, the loop takes control of the main thread and executes that callback. The execution of the normal flow stops while this is happening. This way JavaScript can be imagined as a single-threaded language.
You can learn more about Event Loops and how they work in this amazing talk by Philip Roberts.
Upvotes: 10