简体   繁体   English

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

[英]How to remove a callback registered with a pub/sub datastore?

See the following simple pub/sub-type dataStore which I have implemented: 请参阅以下已实现的简单pub / sub-type dataStore:

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);
    }
}

I am trying to figure out how to implement a removeCallback method for this class, and I am not really getting anywhere. 我试图弄清楚如何为该类实现removeCallback方法,但我实际上什么都没得到。 I can call filter on the callbacks and use !== to find the exact function and remove it, ie: 我可以在callbacks函数上调用filter并使用!==查找确切的函数并将其删除,即:

removeCallback(key, callback) {
    this.callbacks[key].filter( cb => cb !== callback );
}

--but that approach is dependent on having the callback saved, which I wouldn't. -但是这种方法取决于保存回调,而我不会。 See below: 见下文:

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

Since the function passed to onChange was effectively anonymous, how can I identify it? 由于传递给onChange的函数实际上是匿名的,我如何识别它?

The caller of removeCallback needs to have something that uniquely identifies the callback. removeCallback的调用者需要具有唯一标识回调的内容。 The easiest way would be to store the callback in a variable first: 最简单的方法是先将回调存储在变量中:

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

Also note that .filter does not mutate the existing array - you'd need to assign the result of .filter to this.callbacks[key] : 另请注意, .filter不会使现有数组发生变化-您需要将.filter的结果分配给this.callbacks[key]

removeCallback(key, callback) {
  this.callbacks[key] = this.callbacks[key].filter( cb => cb !== callback );
}

You also probably want to change 您可能还想更改

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

to

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

Or, you might use a Set instead, removing the need for .filter and iteration: 或者,您可以改用Set而无需使用.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);
}

If you wanted to be slightly terser, you could have onChange return the passed callback: 如果您想稍微麻烦一点,可以让onChange返回传递的回调:

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

with

onChange(key, callback) {
  this.callbacks[key] = this.callbacks[key] || new Set();
  this.callbacks[key].add(callback);
  return callback;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM