为什么超时在“;点击“;事件循环在Firefox上完成
Why does the timeout fire before the "click" event loop is complete on Firefox?
步骤:
- 在Firefox中运行代码
- 等待5秒(重要!)
- 按"确定"或"取消"
- 期望标志==0,但它是10
var flag;
function myFunction(){
flag = 0
console.info("initial", flag);
setTimeout(function(){
flag = 10;
}, 200);
confirm("conf");
alert("should be 0: "+flag);
}
document.getElementById('button').onclick=myFunction;
<button type="button" id="button">Click Me!</button>
因为与许多浏览器不同,Firefox可能允许JavaScript线程在显示alert
、prompt
和confirm
模式时运行其他代码,从而暂停当前代码。(有关该句中"可能"的更多信息,请参阅答案末尾。)调用alert
等的任务已挂起,因此该任务中的代码不会继续,但允许运行其他任务。
这意味着
-
计时器可以获得他们的回调
-
Ajax完成处理程序可以运行
-
等等。
从来没有JavaScript在两个地方同时运行,但Firefox确实允许线程在任务被这些模式挂起时运行其他任务。
这是Firefox的怪癖。多亏了bobince,我第一次在Stack Overflow上了解到它。
为什么我说"可能"允许JavaScript线程运行:它过去相当可靠(Firefox的旧版本)。我在Firefox 29或38上复制它时没有遇到任何问题。Firefox 42似乎降低了这种可能性,但它确实仍然存在。
我预计(尽管我可能错了)Mozilla会改变这一点,以与其他浏览器保持一致,因为有人可能会认为这违反了JavaScript的任务运行到完成语义,而这些语义刚刚在最新规范中得到了加强和澄清。
我在Firefox和Chrome中都尝试过。在Firefox中,我得到了10
作为结果。在Chrome中,我得到了0
作为结果。当涉及到confirm
函数时,Firefox和Chrome可能有不同的并发模型。Firefox可能在一个单独的线程中运行模式对话框,允许setTimeout
在自己的线程中继续运行(并在200毫秒后递增flag
的值)。Chrome可能在与setTimeout
相同的线程中运行模式对话框,从而阻止setTimeout
的运行(并且不允许flag
的值递增)。
什么?您将标志设置为10。你为什么期望它是0?
- Firefox:点击并更改未附加到文档树中的复选框元素上的事件
- firefox(谷歌地图)中未触发的点击事件
- jQuery切换了Firefox中所需的两次点击
- 右键点击带有firefox的mac上的flash应用程序会触发鼠标按下
- Firefox扩展:获取上下文菜单时的点击数据
- 点击图片关闭Firefox
- 可以't在我的Firefox插件中触发点击事件
- 点击通知后启动Firefox OS应用程序
- 当我在firefox浏览器下点击contenteditable时,它会触发模糊事件
- Impress.js+Firefox:如何禁用鼠标点击时的高级幻灯片
- 在 Greasemonkey 脚本中 – 点击事件不会在 Firefox 中触发
- 是否可以创建一个 Firefox 插件,在网页上生成一个或多个点击事件
- 点击启动的视频不会在 Firefox 中启动,但在 Chrome 中会启动
- 让 jQuery 点击锚点在 Firefox 上工作
- 按钮在 FireFox 中不可点击
- 点击提交按钮使用javascript和Firefox
- 为什么 Mozilla Firefox 页面在 javascript 警报按钮点击后刷新
- 如何在点击 javascript 警报时保留我的 Firefox 首选项
- Facebook喜欢在Firefox中不可点击的按钮iframe实现,可以在其他浏览器中工作
- Firefox 24.0 点击时未在正确的目标上触发