2011-11-04 44 views
3

我有以下问题。我创建了一个类,在它的构造函数中加载了几个图像,我需要延迟其余的初始化,直到它们完全加载。我使用的代码如下(从构造的摘录):JS事件处理程序是否可以中断另一个处理程序的执行?

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,3,2,4读4,4,4,4在IE 9中。我很困惑,因为我相信JS是单线程的,因此一个事件处理程序不应该打断另一个。 (或我的错误)在哪里?

在此先感谢。 此致敬礼, Tomek

+0

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

回答

6

所有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/

+1

这可能是关于警报功能的奇怪之处。 console.log提供正确的4,3,2,1输出,即使在旁边使用时也是如此。此外,我已经注意到== 0条件可以正确解决,即使警报读取4,4,4,4 ... – tomdz

+0

感谢精心制作的简洁答案。 –

相关问题