我在JavaScript WebApp中创建了一个简单的观察者模型来处理更复杂的JS对象模型(无DOM事件)上的事件侦听器。可以注册事件监听器函数,然后将其存储在数组中。通过从模型的更广泛应用中调用成员函数,可以执行事件侦听器。到现在为止还挺好。这里的实施效果很好:在JavaScript中异步调用函数
var ModelObserver = function() {
this.locationObserverList = [];
}
ModelObserver.prototype.emitEvent = function(eventtype, data) {
for(var i=0; i < this.locationObserverList.length; i++) {
var fns = this.locationObserverList[i];
fns(data); // function is being called
}
};
ModelObserver.prototype.registerLocationListener = function(fn) {
this.locationObserverList.push(fn);
};
如果在一个小样本html网站中用两个监听器测试它,一切都很好。
现在我想异步调用该函数。我试图改变相应功能的代码如下:
ModelObserver.prototype.emitEvent = function(eventtype, data) {
for(var i=0; i < this.locationObserverList.length; i++) {
var fns = this.locationObserverList[i];
setTimeout(function() {fns(data);}, 0);
}
};
不幸的是我有一个问题在这里:只有第二监听被调用,但现在的两倍。这似乎是与FNS变量冲突,所以我尝试这样做:
ModelObserver.prototype.emitEvent = function(eventtype, data) {
var fns = this.locationObserverList;
for(var i=0; i < this.locationObserverList.length; i++) {
setTimeout(function() {fns[i](data);}, 0);
}
};
现在,我得到一个错误:“遗漏的类型错误:对象的特性‘2’[对象数组]是不是一个函数”。
有没有人有一个想法如何让这个工作异步?
不要忘记_setTimeout_也接受'的setTimeout(FN,延迟,参数1,参数2,...)在符合标准的浏览器',它可能是值得一提的是,通过使用_setTimout_循环可以在里面没有 - 更长的保证调用顺序。 –
@PaulS .:这是一个相对较新的创新(Mozilla在很久以前就已经做了,其他的只是最近),在野外的重要浏览器(例如IE8,尽管今天是XP的大日子仍然会持续一段时间来吧,拥有6-21%的全球份额取决于你问的对象)。 –
@PaulS .: *“......你不能再保证调用的顺序......”*好点。尽管这一领域的[新]规范](http://www.w3.org/TR/html5/webappapis.html#timers)将其称为定时器的“列表”,暗示着定单,所以在理论计时器中注册按照给定的顺序具有相同的超时值应该按顺序发生,在规范中我没有看到任何要求。 [看起来会发生什么](http://jsbin.com/zavavope/1),但我不想依赖它。 :-) –