Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does JavaScript spawn threads for non-blocking AJAX?

The general perception is that JavaScript is intrinsically single-threaded but it can run asynchronously. I wonder how a single-threaded model like this handles AJAX requests that are non-blocking?

Lets say a non-blocking AJAX request is fired in a browser, but doesn't get a response immediately. If the event loop keeps checking for the response, doesn't the execution get blocked? Does the event loop keeps checking for its status and 're-adding' the task to the back of the macrotask queue when there is no response?

From what I understand, Node.js does silently spawn threads to handle I/O operations accessing disks, databases, network sockets etc. Does JavaScript in browsers spawn threads to handle AJAX too?

A similar question could be asked about the following:

var img = new Image();
img.onerror=function(){alert('error: '+this.src);}
img.onload=function(){alert('image loaded: '+this.src);}
img.src='path/to/image.jpg';

Does the last line of code above causes an additional thread to be spawned, because the statement seems to be non-blocking?

like image 814
Chong Lip Phang Avatar asked Jul 31 '17 11:07

Chong Lip Phang


People also ask

Can I use JavaScript in AJAX?

AJAX is not a programming language. AJAX just uses a combination of: A browser built-in XMLHttpRequest object (to request data from a web server) JavaScript and HTML DOM (to display or use the data)

Is asynchronous JavaScript multithreaded?

Asynchronous Programming vs Multithreading It is a general misconception that both asynchronous programming and multithreading are the same although that's not true. Asynchronous programming is about the asynchronous sequence of Tasks, while multithreading is about multiple threads running in parallel.

Is JavaScript really single threaded?

Now, JavaScript is a single-threaded language, which means it has only one call stack that is used to execute the program.

How does AJAX call work in JavaScript?

How AJAX Calls Work. AJAX uses both a browser built-in XMLHttpRequest object to get data from the web server and JavaScript and HTML DOM to display that content to the user. Despite the name “AJAX” these calls can also transport data as plain text or JSON instead of XML.


1 Answers

The general perception is that JavaScript is intrinsically single-threaded but it can run asynchronously.

It's true that JavaScript is specified¹ such that only a single thread can be executing within a realm at any given time. (A realm is the global environment and its associated objects; e.g. a window/tab [on browsers].) You can have multiple active threads (in different windows, or via web workers), and they can talk to each other (via postMessage) or even share some memory (SharedArrayBuffer), but they can't access the same realm at the same time. Keeping realms effectively single-threaded avoids a huge range of concurrent programming pitfalls.

I wonder how a single-threaded model like this handles AJAX requests that are non-blocking?

JavaScript allowing only one thread within the JavaScript environment at a time doesn't mean that the host (the browser) is single-threaded. An asynchronous ajax request is handed off to the browser's network handling.

JavaScript works on the basis of a job queue (the HTML5 speec calls it a task queue, but the JavaScript spec speaks of "jobs" — it's just a name). The JavaScript thread picks up a job from the queue, runs that job to completion, and then picks up the next job, if any. (It's a bit more complicated than that, but that's the basic idea.) While the thread is running a job, no other thread can run another job in the same realm.

So when an ajax request completes (success, timeout, whatever), the browser (on a non-JavaScript thread, probably) puts a job in the JavaScript job queue to call the ajax callback. The JavaScript thread picks up that job and calls the callback.

It's worth noting that that is also exactly what it does in response to other things that happen, such as the user clicking something.

Lets say a non-blocking AJAX request is fired in a browser, but doesn't get a response immediately. If the event loop keeps checking for the response, doesn't the execution get blocked?

The key is that the thread doesn't continually check back for a response. The thread just watches the job queue. The browser's network handler handles completion of network requests.


¹ This was made explicit in ES2015, but it was the case for common environments (browsers, Node.js) for years prior to that. There were JavaScript environments that allowed multiple threads in a realm (like Rhino, running JavaScript on the Java VM), but they weren't considered important enough to prevent ES2015 adding this requirement, and doing so allowed defining precise semantics around several new features that would have been much more complicated to specify, if it was even possible, while remaining silent on the subject of threading.

like image 184
T.J. Crowder Avatar answered Sep 21 '22 10:09

T.J. Crowder