JavaScript 如何在后台处理 AJAX 响应?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7575589/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does JavaScript handle AJAX responses in the background?
提问by aziz punjani
Since JavaScript runs in a single thread, after an AJAX request is made, what actually happens in the background? I would like to get a deeper insight into this, can anyone shed some light?
由于 JavaScript 在单线程中运行,因此在发出 AJAX 请求后,后台实际发生了什么?我想对此有更深入的了解,有人可以解释一下吗?
回答by jfriend00
Below the covers, javascript has an event queue. Each time a javascript thread of execution finishes, it checks to see if there is another event in the queue to process. If there is, it pulls it off the queue and triggers that event (like a mouse click, for example).
在幕后,javascript 有一个事件队列。每次执行的 javascript 线程完成时,它都会检查队列中是否还有另一个事件要处理。如果有,它会将其从队列中拉出并触发该事件(例如鼠标单击)。
The native code networking that lies under the ajax call will know when the ajax response is done and an event will get added to the javascript event queue. How the native code knows when the ajax call is done depends upon the implementation. It may be implemented with threads or it may also be event driven itself (it doesn't really matter). The point of the implementation is that when the ajax response is done, some native code will know it's done and put an event into the JS queue.
位于 ajax 调用下的本机代码网络将知道 ajax 响应何时完成,并且一个事件将被添加到 javascript 事件队列中。本机代码如何知道 ajax 调用何时完成取决于实现。它可能是用线程实现的,也可能是事件驱动本身(这并不重要)。实现的重点是当ajax响应完成时,一些本机代码会知道它已经完成并将一个事件放入JS队列。
If no Javascript is running at the time, the event will be immediately triggered which will run the ajax response handler. If something is running at the time, then the event will get processed when the current javascript thread of execution finishes. There doesn't need to be any polling by the javascript engine. When a piece of Javascript finishes executing, the JS engine just checks the event queue to see if there is anything else that needs to run. If so, it pops the next event off the queue and executes it (calling one or more callback functions that are registered for that event). If nothing is in the event queue, then the JS interpreter has free time (garbage collection or idle) until some external agent puts something else in the event queue and wakes it up again.
如果当时没有 Javascript 正在运行,将立即触发该事件,该事件将运行 ajax 响应处理程序。如果当时正在运行某些东西,那么当当前的 javascript 执行线程完成时,将处理该事件。javascript 引擎不需要进行任何轮询。当一段 Javascript 完成执行时,JS 引擎只会检查事件队列,看看是否还有其他需要运行的东西。如果是,它将从队列中弹出下一个事件并执行它(调用为该事件注册的一个或多个回调函数)。如果事件队列中没有任何内容,则 JS 解释器有空闲时间(垃圾收集或空闲),直到某个外部代理将其他内容放入事件队列并再次唤醒它。
Because all outside events go through the event queue and no event is ever triggered while javascript is actually running something else, it stays single threaded.
因为所有外部事件都通过事件队列,并且当 javascript 实际运行其他东西时不会触发任何事件,所以它保持单线程。
Here are some articles on the details:
这里有一些关于细节的文章:
- How Javascript Timers Work - written by John Resig
- Events and Timing in Depth
- W3 spec: HTML5 event loops
- MDN article on Event Loop
- Presentation on JS event queue
- The JavaScript Event Loop: Explained
- Five Patterns to Help Tame Asynchronous Javascript
- Javascript Event Loop Presentation
- Video Discussing How Javascript Works (including event loop at 10:27)
回答by qwertzguy
You can find herea very complete documentation on events handling in javascript.
It is written by a guy working on the javascript implementation in the Opera Browser.
您可以在此处找到有关 javascript 中事件处理的非常完整的文档。
它是由一个在 Opera 浏览器中处理 javascript 实现的人编写的。
More precisely, look at the titles: "Event Flow", "Event Queuing" and "Non-user Events": you'll learn that:
更准确地说,查看标题:“事件流”、“事件队列”和“非用户事件”:您将了解到:
- Javascript runs in a single thread for each browser tab or window.
- Events are queued and executed sequentially.
- XMLHttpRequest are run by the implementation and callbacks are run using the event queue.
- 对于每个浏览器选项卡或窗口,Javascript 在单个线程中运行。
- 事件排队并按顺序执行。
- XMLHttpRequest 由实现运行,回调使用事件队列运行。
Note: Original link was: link, but is now dead.
注意:原始链接是:link,但现在已失效。
回答by shmulik friedman
I want to elaborate a bit, regarding the ajax Implementation mentioned in answers.
我想详细说明一下,关于答案中提到的 ajax 实现。
Although (regular) Javascript execution is notmulti-threaded - as noted well in the above answers - however,
the real handling of the AJAX responses
(as well as the request handling) is notJavascript, and it - usually - ismulti-threaded. (see chromium source implementationof XMLHttpRequest which we'll discus above)
尽管(常规)Javascript 执行不是多线程的 - 正如上面的答案中所指出的那样 -但是,AJAX responses
(以及请求处理)的真正处理不是Javascript,而且它 - 通常 -是多线程的。(请参阅我们将在上面讨论的 XMLHttpRequest 的铬源实现)
and I'll explain, let's take the following code:
我会解释一下,让我们使用以下代码:
var xhr = new XMLHttpRequest();
var t = Date.now;
xhr.open( "GET", "https://swx.cdn.skype.com/shared/v/1.2.15/SkypeBootstrap.min.js?v="+t(), true );
xhr.onload = function( e ) {
console.log(t() + ': step 3');
alert(this.response.substr(0,20));
};
console.log(t() + ': step 1');
xhr.send();
console.log(t() + ': step 2');
after an AJAX request is made
(- after step 1),
then while your js code proceeds executing (step 2 and after), the browser starts the real work of: 1. formatting a tcp request 2. opening a socket 3. sending headers 4. handshaking 5. sending body 6. waiting response 7. reading headers 8. reading body etc. all of this implementation is usually run's in a different thread in parallel to your js code execution. for an example, chromium implementation mentioned uses ThreadableLoadergo digg-into , (you can also get some impression by looking at network tab of a page load, you'll see some simultaneous requests).
after an AJAX request is made
(- 在第 1 步之后),然后当您的 js 代码继续执行(第 2 步及之后)时,浏览器开始真正的工作: 1. 格式化 tcp 请求 2. 打开套接字 3. 发送标头 4. 握手 5. 发送主体 6. 等待响应 7. 读取标头 8. 读取主体等 所有这些实现通常在不同的线程中运行,与您的 js 代码执行并行。例如,提到的chromium实现使用ThreadableLoadergo digg-into,(您也可以通过查看页面加载的网络选项卡获得一些印象,您会看到一些并发请求)。
in conclusion, I would say that - at least - most of your I/O operations can be made simultaneously/async (and you can take advantage of this using an awaitfor example). but all interaction with those operations (the issuing, the js callback execution) are all synchronous.
总之,我会说 - 至少 - 您的大部分 I/O 操作可以同时/异步进行(例如,您可以使用await来利用这一点)。但是与这些操作的所有交互(发布、js 回调执行)都是同步的。