我想建立一个观察者/听众系统:
var listeners = [];
function MyObj(){
this.myMethod = function(){
// react to event
}
}
var myObj = new MyObj();
function addListener(fn, obj){
alliancesNotify[alliancesNotify.length] = {fn: fn, obj: obj}
}
addListener(myObj, myObj.myMethod); // Best way of doing it?
function notify(objArr){
for (var i in objArr){
objArr[i].obj.fn(); // will this work?
}
}
notify(listeners);
我希望您能对两条注释行提出想法(如果它实际上能按预期运行),以及是否存在通过调用对象的方法来通知对象的更直接的方法。 (例如,我注意到某些实现将函数名称作为字符串而不是对函数的引用来传递,而不是通过这种方式。)
谢谢
最佳答案
好吧,首先有一个多个问题,让我们一个个地解决:objArr[i].obj.fn();
不会做您期望的事情。它会查找并调用fn方法,但是您期待从obj调用myMethod
。要解决此问题,您有多种选择。使用apply
或call
。因此您的代码将类似于objArr[i].fn.call(objArr[i].obj)
。这就是像jQuery或Mootools或PrototypeJS这样的优秀JS库如何做到的。
第二个问题,如果回调函数引发异常并出现错误怎么办?在某些浏览器中,循环将停止迭代,因此将导致不再调用任何回调(函数)。解决方案可以再次成为多种解决方案,要么使用try catch块,要么执行我最喜欢的方法。使用setTimeout
,因此您的代码将如下所示,由于JS是单线程浏览器,因此将使回调函数排队,即使出现错误,其余部分也不会受到影响。
函数notify(objArr){
为(varI in objArr){
window.setTimeout(function(){objArr [i] .call(objArr [i] .obj);},0);
}
}
绝对不是最佳解决方案,而是接近最佳解决方案,因此请浏览(Google it)周围的许多库进行改进。我自己编写了一个这样的独立PUB SUB库用于事件管理check it out here