【问题标题】:Can JS event handlers interrupt execution of another handler?JS 事件处理程序可以中断另一个处理程序的执行吗?
【发布时间】:2011-11-04 21:34:25
【问题描述】:

我有以下问题。我创建了一个类,我在其构造函数中加载了几个图像,我需要延迟剩余的初始化,直到它们完全加载。我使用的代码如下(摘自构造函数):

var self = this;
var imagesToLoad = 4;

var finishInit = function() {
    alert(imagesToLoad);
    imagesToLoad--;
    if (imagesToLoad == 0) {
       // remaining initializations
    }
}

this._prevIcon = new Image();
this._prevIcon.onload = finishInit; 
this._prevIcon.src = "img1.png";
this._nextIcon = new Image();
this._nextIcon.onload = finishInit; 
this._nextIcon.src = "img2.png";
this._pauseIcon = new Image();
this._pauseIcon.onload = finishInit; 
this._pauseIcon.src = "img3.png";
this._playIcon = new Image();
this._playIcon.onload = finishInit; 
this._playIcon.src = "img4.png";

令我惊讶的是,执行时显示的对话框在 Firefox 7 中显示为 4,4,4,4,在 IE 9 中显示为 4,3,2,4。我很困惑,因为我认为 JS 是单线程的,因此一个事件处理程序不应中断另一个。问题在哪里(或我的错误)?

提前致谢。 最好的祝福, 托梅克

【问题讨论】:

  • 尝试在 'src' 和 'onload' 行之间切换。

标签: javascript events


【解决方案1】:

所有 JS 事件处理程序都是单线程的。在前一个完成之前,一个不会开始。这一切都通过事件队列进行。当一个事件完成时,JS 引擎会查看队列中是否有另一个事件,如果有,则开始执行该事件。

例如,当一个定时器触发指示它的定时器事件时间到时,它会将事件放入队列中,并且当当前执行的 JS 事件完成并且定时器事件到达顶部时,该定时器事件的代码会触发队列。

有关 Javascript 事件队列的进一步讨论,请参阅 this post

使用本机操作系统网络在后台加载图像。可以一次加载多个图像。 .onload() 处理程序一次只会触发一个,但由于图像同时加载,因此无法保证代码中的加载顺序。此外,警报会影响时间,因为它们会阻止 javascript 的执行,但不会阻止图像加载的执行。

我不理解 4,4,4,4 或 4,3,2,4 序列。他们都应该显示 4,3,2,1。你必须向我们展示一个完整的代码版本才能知道是什么原因造成的。我猜你要么有你的变量的范围问题,这些变量跟踪你的代码中发生的事情比你在问题中披露的要多。

您可以在此处查看此类代码的工作版本:http://jsfiddle.net/jfriend00/Bq4g3/

【讨论】:

  • 警报功能可能有点奇怪。 console.log 给出正确的 4,3,2,1 输出,即使在警报旁边使用也是如此。另外,我注意到即使警报读取为 4,4,4,4..., == 0 条件也已正确解决...
  • 感谢详细而简洁的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多