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

azi*_*ani 136 javascript xmlhttprequest

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

jfr*_*d00 208

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

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

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

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

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

  • @telandor - 事件以FIFO顺序运行(可能存在一些边缘情况异常,但意图是FIFO).有些事件的处理略有不同.例如,mousemove事件不会堆积在队列中(可能是因为它们很容易溢出队列).当鼠标移动并且mousemove事件已经在队列中并且队列中没有其他更新的事件时,它将使用最新位置而不是添加新事件进行更新.我猜测间隔计时器事件也可能是专门处理的,以避免它们堆积在队列中. (4认同)
  • @telandor - 您需要进一步解释什么?它是FIFO.我在答案中添加了一些参考文章.我所知道的FIFO的唯一执行是立即触发的事件.你在一个项目上调用`.focus()`并触发一些其他事件,例如具有焦点的项目上的"模糊"事件.该模糊事件同步发生,并且不会通过事件队列,因此它会在事件队列中可能存在的其他事件之前立即发生.在实践中,我从未发现这是一个实际问题. (2认同)
  • @telandor - 每个浏览器文档没有多个队列.有一个队列,所有内容都按顺序进行FIFO输入/输出.因此,超时和ajax响应以及鼠标事件和键盘事件都在同一队列中.首先放入队列中的任何一个都先运行. (2认同)

qwe*_*guy 16

你可以在这里找到一个关于javascript事件处理的非常完整的文档.
它是由一个致力于Opera浏览器中的javascript实现的人编写的.

更准确地说,看看标题:"事件流","事件排队"和"非用户事件":您将了解到:

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

注意:原始链接是:链接,但现在已经死了.