JavaScript如何在后台处理AJAX响应?

JavaScript如何在后台处理AJAX响应?,javascript,xmlhttprequest,Javascript,Xmlhttprequest,由于JavaScript在单个线程中运行,在发出AJAX请求后,在后台实际发生了什么?我想更深入地了解这一点,有人能解释一下吗 在封面下面,javascript有一个事件队列。每次javascript执行线程完成时,它都会检查队列中是否有其他事件要处理。如果有,它会将其从队列中拉出来并触发该事件(例如,单击鼠标) ajax调用下的本机代码网络将知道ajax响应何时完成,事件将添加到javascript事件队列中。本机代码如何知道何时完成ajax调用取决于实现。它可以用线程实现,也可以是事件驱动的

由于JavaScript在单个线程中运行,在发出AJAX请求后,在后台实际发生了什么?我想更深入地了解这一点,有人能解释一下吗

在封面下面,javascript有一个事件队列。每次javascript执行线程完成时,它都会检查队列中是否有其他事件要处理。如果有,它会将其从队列中拉出来并触发该事件(例如,单击鼠标)

ajax调用下的本机代码网络将知道ajax响应何时完成,事件将添加到javascript事件队列中。本机代码如何知道何时完成ajax调用取决于实现。它可以用线程实现,也可以是事件驱动的(其实并不重要)。实现的要点是,当ajax响应完成时,一些本机代码将知道它已经完成,并将事件放入JS队列

如果当时没有运行Javascript,将立即触发事件,该事件将运行ajax响应处理程序。如果当时正在运行某个东西,那么当当前javascript执行线程完成时,事件将得到处理。javascript引擎不需要进行任何轮询。当一段Javascript完成执行时,JS引擎只需检查事件队列,查看是否还有其他需要运行的内容。如果是这样,它将从队列中弹出下一个事件并执行它(调用为该事件注册的一个或多个回调函数)。如果事件队列中没有任何内容,那么JS解释器有空闲时间(垃圾收集或空闲),直到某个外部代理将其他内容放入事件队列并再次将其唤醒

因为所有外部事件都通过事件队列,并且javascript实际运行其他内容时不会触发任何事件,所以它保持单线程

以下是一些关于细节的文章:

您可以找到关于javascript事件处理的非常完整的文档。
它是由一个在Opera浏览器中开发javascript实现的家伙编写的

更准确地说,请看标题:“事件流”、“事件队列”和“非用户事件”:您将了解:

  • Javascript在每个浏览器选项卡或窗口的单个线程中运行
  • 事件排队并按顺序执行
  • XMLHttpRequest由实现运行,回调使用事件队列运行

  • 注意:原来的链接是:,但现在已经死了。

    我想详细介绍一下答案中提到的ajax实现

    尽管(常规)Javascript执行不是多线程的,正如上面的答案所指出的,但是,
    AJAX响应的真正处理(以及请求处理)是而不是Javascript,而且它通常是多线程的。(请参阅我们将在上面讨论的XMLHttpRequest)

    我会解释,让我们看下面的代码:

    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(),真);
    xhr.onload=函数(e){
    log(t()+':步骤3');
    警报(this.response.substr(0,20));
    };
    log(t()+':步骤1');
    xhr.send();
    
    log(t()+':步骤2')这里有一个很好的描述:JavaScript代码是单线程的(web workers除外),但不是运行JavaScript引擎的浏览器…@JuanMendes JavaScript是否在一个线程中运行,而事件队列在另一个线程中运行?@ShaunLuttin不,事件队列是JavaScripts的起点谢谢。我怀疑是这样的,但很高兴能确定。我有一个for循环,在这个循环中我发送了很多“ajax”请求。在我的处理程序中(对于每个以任意顺序返回的请求),我运行一些可能需要一些时间的代码。很高兴知道这肯定会起作用。@telandor-事件以FIFO顺序运行(可能存在一些边缘情况例外,但目的是FIFO)。有些事件的处理略有不同。例如,mousemove事件不会堆积在队列中(可能是因为它们很容易使队列溢出)。当鼠标移动且mousemove事件已在队列中且队列中没有其他较新的事件时,将使用最新位置而不是添加新事件来更新该事件。我猜间隔计时器事件可能也被特别处理,以避免它们堆积在队列中。@telandor-您需要进一步解释什么?这是先进先出。我在回答中又添加了几篇参考文章。我所知道的对FIFO的唯一执行是立即触发事件。您对一个项目调用
    .focus()
    ,这会触发一些其他事件,例如对具有焦点的项目的“模糊”事件。该模糊事件是同步发生的,不会经过事件队列,因此它会在事件队列中的其他事件之前立即发生。实际上,我从未发现这是一个实际问题。@telandor-每个浏览器文档没有多个队列。有一个队列,所有的东西都按顺序FIFO输入/输出。所以超时、ajax响应、鼠标事件和键盘事件都在同一个队列中。无论谁先进入队列,都会首先运行。@CleanCrispCode-Thx。我把它作为我答案的有用参考。