我正在尝试为我的Javascript应用程序构建基于信号的系统,并且我有类似的东西:
class EventHubListener {
constructor(eventName, callback, errorHandling) {
this.eventName = eventName;
this.callback = callback;
this.errorHandling = errorHandling;
}
}
class EventsHub {
constructor() {
this.listeners = [];
this.idgen = 0;
this.defaultErrorHandler = null;
}
registerListener(listenerInstance) {// EventHubListener
this.listeners.push(listenerInstance);
return listenerInstance.id = ++idgen;
}
register(eventName, callback, errorHandling) {
return registerListener(new EventHubListener(eventName, callback, errorHandling));
}
watchRemoteChange(type, field, callback, handling) {
return register('EvtRemoteStateChange', (data)=> {
if(!data || data.ObjectType !== type || !data.ChangedObject)
return;
callback(data.changedObject.id, data.ChangedObject[field]);
}, handling);
}
unregisterListener(id) {
this.listeners = this.listeners.filter(i=> i.id != id);
}
raise(eventName, data) {
this.listeners.forEach(l=> l.eventName === eventName, listener=> {
try {
if(listener.eventName === eventName)
listener.callback(data);
} catch(err) {
if(listener.errorHandling) {
try {
listener.errorHandling(err);
} catch(internalError) {
this.handleError(internalError);
}
} else {
this.handleError(err);
}
}
});
}
handleError(err) {
if(this.defaultErrorHandler) {
try {
this.defaultErrorHandler(err);
} catch(errorHandlingError) {
console.trace('Error in the default error handling routine', err, errorHandlingError);
}
} else {
throw internalError;
}
}
}
// use
hub.watchRemoteChange('Products', 'SellingPrice', (id, value)=> {
console.writeLine(`Product ${id} has changed price to ${value}!`);
});
这里的问题是,我想这个“使用”示例将使Hub类持有对该匿名函数的引用:
(id, value)=> {
console.writeLine(`Product ${id} has changed price to ${value}!`);
}
在此示例中,这似乎不是什么大问题,但它可能使用了闭包中的值,以防在收集用户类的情况下最终收集到这些值(我想是吗?),我这里需要的是一种方法要检测到用户类已被处置,并使集线器类停止持有它们或它们的闭包,并可能避免执行损坏的闭包,是否有办法在库侧做到这一点,或者我必须始终手动管理从中注销我的侦听器用户代码?