js:了解alert()如何影响浏览器事件循环

Dus*_*etz 17 javascript winapi javascript-events settimeout

我正在考虑向我们的javascript实用程序断言函数添加alert().

我们是一个ajax繁重的应用程序,我们的框架(Ext)通过使用setInterval轮询ajax响应而不是等待readystate == 4来实现ajax的方式,导致我们所有的ajax回调在setInterval堆栈上下文中执行 - - 一个异常/断言吹出它通常会无声地失败.

低级别alert()如何影响浏览器事件循环?根据定义,消息框必须允许win32事件循环泵(响应mbox按钮).这是否意味着其他浏览器事件,就像我们的框架生成的未来setIntervals,调整大小事件等,要火?这会给我带来麻烦吗?

IIRC:您可以使用FF2和FF3.5来查看我正在谈论的差异.

alert('1');
setTimeout(function(){alert('2');}, 10);
alert('3');
Run Code Online (Sandbox Code Playgroud)

FF 3.5显示1-3-2.FF2 [1]显示1-2和3(2和3同时堆叠在一起).我们可以使用从activex启动的win32 mbox在IE8中复制1-2和3,而不是在当天对我们造成严重破坏的警报,我想确保我们不再沿着那条路走下去.

任何人都可以向我指出解释这种行为的特定低级资源,这里的预期行为是什么,以及在低级别上究竟发生了什么,包括为什么行为在FF版本中发生了变化?

[1]你可以在Spoon.net上复制这个,我现在无法正常工作.我只是用FF 2.0.0.20在vm中重新编写它.

Ric*_*asi 7

首先,javascript中的计时器不是很精确.小于30ms的间隔可能被认为是完全相同的,并且实现方式也各不相同.不要依赖任何隐式排序.

alert()将始终停止事件循环.如果事件或计时器在警报期间触发,它们将在事件循环恢复后排队并调用(警报框关闭).

举个例子:

var hello = document.getElementById('hello')

setTimeout(function(){
  hello.style.backgroundColor = 'lime'
}, 5000)

alert('Stop!')

setTimeout(function(){
  hello.innerHTML = 'collaborate'
}, 20)

setTimeout(function(){
  hello.innerHTML = 'listen'
}, 1000)
Run Code Online (Sandbox Code Playgroud)

有两种可能的结果:

  1. 您在5秒内关闭警报框.随后的两个计时器将按指定的间隔设置和触发.您可以看到事件循环已停止,因为无论您等待关闭警报多长时间,"listen"将始终执行1秒.

  2. 您需要超过5秒才能关闭警报.第一个间隔(bgColor)将通过,因此它立即执行,然后设置和调用两个定时器.

http://jsbin.com/iheyi4/edit

至于间隔,当事件循环停止时它也"停止时间",所以在这种情况下:

i = 0

setInterval(function(){
  document.getElementById('n').innerHTML = ++i
}, 1000)

setTimeout(function(){
  alert('stop')
}, 5500)
Run Code Online (Sandbox Code Playgroud)

无论您关闭警报需要多长时间,下一个数字将始终为6 - setInterval不会多次触发.

http://jsbin.com/urizo6/edit


Bri*_*y37 1

我无法复制 1-2&3 的情况,但这里有一个小提琴可以帮助您调试不同浏览器中发生的情况。