JS事件处理程序可以中断执行另一个处理程序吗? [英] Can JS event handlers interrupt execution of another handler?

查看:131
本文介绍了JS事件处理程序可以中断执行另一个处理程序吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  var self = this; 
var imagesToLoad = 4;

var finishInit = function(){
alert(imagesToLoad);
imagesToLoad--;
if(imagesToLoad == 0){
//剩余的初始化
}
}

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



提前感谢。
最好的问候,
Tomek

解决方案

所有JS事件处理程序都是单线程的。一个人不会开始,直到前一个完成。它都通过事件队列工作。当一个事件结束时,JS引擎看起来会看到队列中是否有另一个事件,如果是,则启动该事件的执行。



例如,当定时器触发指示它是定时器事件的时间时,它将事件置于队列中,并且当该当前执行的时候该定时器事件的代码被触发JS事件完成并且计时器事件到达队列的顶部。



请参阅这篇文章,以进一步讨论Javascript事件队列。



图像在后台使用本机OS网络加载。可以一次加载多张图像。 .onload()处理程序只会一次启动一个,但是由于图像同时加载,所以不能像代码那样在代码中保证加载顺序。此外,警报可能会影响时序,因为它们阻止执行javascript,但不会阻止图像加载的执行。



我不明白4,4, 4,4或4,3,2,4序列。他们都应该显示4,3,2,1。你必须向我们展示一个完整的代码,以了解是什么导致的。我想你可能会遇到与变数有关系的范围问题,跟踪您的代码中所发生的更多的错误。



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


I have the following problem. I've created a class in whose constructor I'm loading a couple of images and I need to delay the remaining initializations until they are completely loaded. The code I used is as follows (an excerpt from the constructor):

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";

To my surprise, when executed the displayed dialogs read 4,4,4,4 in Firefox 7 and 4,3,2,4 in IE 9. I'm confused becaused I believed that JS is single-threaded and thus one event handler should not interrupt another. Where's the catch (or my mistake)?

Thanks in advance. Best regards, Tomek

解决方案

All JS event handlers are single threaded. One will not start until the previous one finishes. It all works through an event queue. When one event finishes, the JS engine looks to see if there's another event in the queue and, if so, starts execution of that event.

For example, when a timer fires indicating it's time for a timer event, it puts the event in the queue and it the code for that timer event fires when the currently executing JS event is finished and the timer event gets to the top of the queue.

See this post for further discussion of the Javascript event queue.

Images load in the background using native OS networking. Multiple images can be loading at once. .onload() handlers will only fire one at a time, but since images load simultaneously, there is no guarantee of load order in code like you have. Further, alerts can influence the timing because they block execution of javascript, but don't block execution of image loading.

I don't understand either the 4,4,4,4 or the 4,3,2,4 sequence. They both should show 4,3,2,1. You'd have to show us a fully working version of code to know what is causing that. I'd guess that you either have scoping issues with your variables that keep track of the count of there's more going on in your code than you've disclosed in your question.

You can see a working version of this kind of code here: http://jsfiddle.net/jfriend00/Bq4g3/.

这篇关于JS事件处理程序可以中断执行另一个处理程序吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆