异步计时器事件在 Firefox 4 中同步运行(“有问题”)?

发布于 2024-11-08 13:25:04 字数 1506 浏览 0 评论 0原文

这是在 Firefox 4 (4.0.1) 中; Firefox 3 (Firefox 3.6.17)、IE 9 (9.0.8112.16421) 和 Chrome 11 (11.0.696.68) 中的警报顺序“按预期”。

预期的警报顺序为“Now”、“Wait-End(x)”、“End(x)”,其中 x 是相同的数字。

但是,观察到的顺序是“Now”、“End(0)”、“Wait-End(x)”。为什么setTimeoutwhile之后异步运行?正如计数器所示,这似乎可能非常有问题这是以下测试用例的 jsfiddle

function doLater(callback) {
    // if the timeout is larger than about 800ms it "works as expected"
    setTimeout(callback, 1)
    alert("Now")
}

var waiting = 0;
doLater(function () { alert("End(" + waiting + ")") })
var end = (+new Date) + 2000
while ((+new Date) < end) { waiting++ }
alert("Wait-End(" + waiting + ")")

如果计时器超时时间超过大约 800 毫秒,就会发生预期的行为。(100 毫秒和 500 毫秒的超时仍然表现出意外的顺序)。

这看起来真的像一个错误。


更新:这部分是海森堡的。以下内容按预期工作。 Firefox 4.0.1 中的 alert 似乎将处理待处理事件(何时关闭?)。 jsfiddle 和代码:

function doLater(callback) {
    setTimeout(callback, 1)
    console.log("Now")
}

var waiting = 0;
doLater(function () { console.log("End(" + waiting + ")") })
var end = (+new Date) + 2000
while ((+new Date) < end) { waiting++ }
console.log("Wait-End(" + waiting + ")")

有了这些新信息,Firefox 4 的警报行为仍然可以在适用的 Javascript / 中运行吗?事件模型规范?特别是,调用警报的代码仍然是“活动的”,但效果是它暂时被事件处理抢占。

This is in Firefox 4 (4.0.1); The order of alerts is "as expected" in Firefox 3 (Firefox 3.6.17), IE 9 (9.0.8112.16421), and Chrome 11 (11.0.696.68).

The expected order of alerts is "Now", "Wait-End(x)", "End(x)", where x is some number that is the same.

However, the observed order is "Now", "End(0)", "Wait-End(x)". Why does setTimeout not run asynchronously after the while? This seems like it could be very problematic, as shown with the counter. Here is the jsfiddle for the following test case:

function doLater(callback) {
    // if the timeout is larger than about 800ms it "works as expected"
    setTimeout(callback, 1)
    alert("Now")
}

var waiting = 0;
doLater(function () { alert("End(" + waiting + ")") })
var end = (+new Date) + 2000
while ((+new Date) < end) { waiting++ }
alert("Wait-End(" + waiting + ")")

If the timer timeout is above ~800ms then the expected behavior occurs. (Timeouts of 100ms and 500ms still exhibit the unexpected order).

It really seems like a bug.


Update: This partially a Heisenberg. The following works as expected. It appears that alert in Firefox 4.0.1 will process pending events (when closed?). The jsfiddle and code:

function doLater(callback) {
    setTimeout(callback, 1)
    console.log("Now")
}

var waiting = 0;
doLater(function () { console.log("End(" + waiting + ")") })
var end = (+new Date) + 2000
while ((+new Date) < end) { waiting++ }
console.log("Wait-End(" + waiting + ")")

With this new information, does Firefox 4's alert behavior still operate within applicable Javascript / event-model specifications? In particular, the code which invoked the alert is still "active" but the effect is that it is being momentarily preempted with event processing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

满意归宿 2024-11-15 13:25:04

你的脚本可以在我的 Firefox 3.6.17 中运行。

我做了一些搜索...看起来 Firefox 3 在处理警报时实际上停止了 JavaScript 线程。然而,其他同步操作(例如 XMLHttpRequest)使用了称为“事件循环”的东西,这显然不会阻止其他计时器的执行。

我的猜测是,Firefox 4 现在对 alert 所做的事情与 Firefox 3 对 XMLHttpRequest 所做的事情一样;它使用事件循环,因此计时器在警报“后面”运行。这似乎可以解释为什么它对我有用(在 FF3 中)但对你不起作用(在 FF4 中)。

FF3 信息来源。

Your script works in my Firefox 3.6.17.

I did some searching... It would seem that Firefox 3 actually halted the JavaScript thread(s) when processing an alert. However, other synchronous operations (like XMLHttpRequest) instead used something called an "event loop", which apparently doesn't stop other timers from executing.

My guess is that Firefox 4 is now doing for alert what Firefox 3 did for XMLHttpRequest; it's using an event loop, and because of this, timers run "behind" alerts. This would seem to explain why it works for me (in FF3) but not for you (in FF4).

Source for the FF3 information.

究竟谁懂我的在乎 2024-11-15 13:25:04

我想说,您看到“预期”行为的唯一原因是,您在浏览器的计时器有机会触发回调之前,在 while 循环中引入了一个块。在您的 doLater 中,您已指示 JavaScript 引擎尽快执行 callback 函数。但是,您随后立即引入一条指令,该指令将占用大多数 JavaScript 引擎,因此回调必须等待。因此,FireFox 4 的 JavaScript 引擎在这种情况下必须比其他引擎快一些。

I'd say the only reason you are seeing your "expected" behavior is because you are introducing a block with your while loop before the browser's timer has had a chance to fire your callback. In your doLater you have instructed the JavaScript engine to execute the callback function as soon as possible. However, you then immediately introduce an instruction that will tie up most JavaScript engines so that the callback has to wait. So FireFox 4's JavaScript engine must be a bit quicker in this instance than the others.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文