Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/428.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何删除在发布/订阅数据存储中注册的回调?_Javascript - Fatal编程技术网

Javascript 如何删除在发布/订阅数据存储中注册的回调?

Javascript 如何删除在发布/订阅数据存储中注册的回调?,javascript,Javascript,请参阅我已实现的以下简单发布/子类型数据存储: class DataStore { constructor() { this.store = {}; this.callbacks = {}; } getState(key) { return this.store[key]; } setState(key, value) { this.store[key] = value;

请参阅我已实现的以下简单发布/子类型数据存储:

class DataStore {
    constructor() {
        this.store = {};
        this.callbacks = {};
    }

    getState(key) {
        return this.store[key];
    }

    setState(key, value) {
        this.store[key] = value;
        this.callbacks[key].forEach( callback => {
            callback(this.store[key]);
        });
    }

    onChange(key, callback) {
        this.callbacks[key] = this.callbacks.key || [];
        this.callbacks[key].push(callback);
    }
}
我正在试图找出如何为这个类实现
removeCallback
方法,但我并没有真正取得任何进展。我可以在
回调中调用
过滤器
,并使用
==
查找确切的函数并将其删除,即:

removeCallback(key, callback) {
    this.callbacks[key].filter( cb => cb !== callback );
}
--但这种方法依赖于保存回调,而我不会保存回调。见下文:

store.onChange('someValue', val => { /* do something with val */ });
store.removeCallback('someValue', ???);

由于传递给
onChange
的函数实际上是匿名的,如何识别它?

调用
removeCallback
的调用方需要具有唯一标识回调的内容。最简单的方法是首先将回调存储在变量中:

const cb = val => { /* do something with val */ };
store.onChange('someValue', cb);
store.removeCallback('someValue', cb);
还请注意,
.filter
不会改变现有数组-您需要将
.filter
的结果分配给
此数组。回调[key]

removeCallback(key, callback) {
  this.callbacks[key] = this.callbacks[key].filter( cb => cb !== callback );
}
你也可能想要改变

this.callbacks[key] = this.callbacks.key || [];

或者,您可以使用
集合
,这样就不需要
.filter
和迭代:

onChange(key, callback) {
  this.callbacks[key] = this.callbacks[key] || new Set();
  this.callbacks[key].add(callback);
}
removeCallback(key, callback) {
  this.callbacks[key].delete(callback);
}
如果您想稍微简洁一点,可以让
onChange
返回传递的回调:

const cb = store.onChange('someValue', (val) => { ... });


当然可以,但是如果回调创建代码被调用两次,然后您想要删除第一个呢?或者,为了更清楚并跳转到问题的真正核心,如果创建回调的代码被调用N次,然后您想要删除第N-kt次,那么
onChange
会被同一个回调调用多次呢?这有点奇怪,您希望在这种情况下触发回调时运行两次吗?(注意,类似的机制,如<代码> AdvestTraceNistabue/Cult>,将忽略重复添加的处理程序——它就像一个<代码> SET>代码>——在附加回调的性质是运行时用户选择依赖的情况下,您也可以考虑使用这类功能。如果传递的回调不相同,那么就不应该有问题-只要将回调保存在变量中,并在要删除它们时使用这些变量调用
removeCallback
。(为了更好地组织,可以随意使用此类回调的对象或数组,如果需要,可以连接到类)
const cb = store.onChange('someValue', (val) => { ... });
onChange(key, callback) {
  this.callbacks[key] = this.callbacks[key] || new Set();
  this.callbacks[key].add(callback);
  return callback;
}