【问题标题】:JS How to check if callback is exist?JS如何检查回调是否存在?
【发布时间】:2017-02-24 23:02:37
【问题描述】:

我有一组已注册的回调

this.events[eventName].push({callback: callback});

问题是,在数组中的用户操作之后可以添加相同的回调,它已经存在。

如何检查回调是否存在?

如果两个相同的回调从两个不同的代码位置注册,会发生什么?应该执行它们是合乎逻辑的。问题是,如何不在同一个地方重新注册回拨电话。

【问题讨论】:

  • 来自同一个地方”是什么意思?一个函数没有任何关于它被调用的执行上下文的概念。它知道自己的上下文并且对外部上下文的变量有闭包,但是你不能以任何方式引用上下文,所以也不能传递引用。我认为您需要发布minimal, complete and verifiable example 以提供更多详细信息。

标签: javascript callback call


【解决方案1】:

适合这种情况的数据结构是 ES6 Map。如果您使用它而不是数组,它将自动只存储唯一性:

this.events = new Map(); // one time initialisation instead of `this.events = []`;
// ...
this.events[eventName].set(callback, {callback: callback});

并按如下方式执行事件的回调:

this.events[eventName].forEach(({callback}) => callback());

如果回调是您存储的唯一内容,那么您可以改用Set

this.events = new Set();
// ...
this.events[eventName].add(callback);

并按如下方式执行事件的回调:

this.events[eventName].forEach(callback => callback());

【讨论】:

    【解决方案2】:

    您可以使用Array.prototype.some() 来测试回调是否已经存在:

    if (!this.events[eventName].some(function(el) {
        return el.callback == callback;
    }) {
        this.events[eventName].push({callback: callback});
    }
    

    【讨论】:

    • 如果两个相同的回调从两个代码位置注册,会发生什么?应该执行它们是合乎逻辑的。您的解决方案不会注册第二个回调。问题是,如何不在同一个地方重新注册回拨电话。
    • 没有办法知道回调是从哪里注册的。为什么要有所作为?要么允许重复回调,要么不允许。
    • 我不知道el.callback == callback中的比较,如果这是函数指针,是的,它应该很好用。
    • 是的,它比较函数指针。调用者每次都需要传递 same 函数——匿名函数可能不匹配,因为闭包环境不同。
    • 如果匿名函数是不同的函数,则它们将不匹配:function(){} !== function(){}。 ;-)
    【解决方案3】:

    用一个简单的循环?

    for (var i = 0; i < this.events[eventName].length; i++)
      if (this.events[eventName].callback === callback)
        return;    // already exists, so return without pushing
    
    this.events[eventName].push({callback: callback});
    

    【讨论】:

    • 如果两个相同的回调从两个代码位置注册,会发生什么?应该执行它们是合乎逻辑的。您的解决方案不会注册第二个回调。问题是,如何不在同一个地方重新注册回拨电话。
    • 我不明白你的意思。我的代码检查是否已将 specific 函数添加到数组中。如果您从代码的不同部分注册回调,它们可能不是同一个函数,因此两者都会注册。如果您使用匿名函数,即使在代码的同一部分,它们也将被视为彼此相同。
    【解决方案4】:

    你可以使用Array.prototype.some函数来检查回调是否存在

    class Observer {
      constructor(){
        this.events = {};
      }
      
      on(name, callback){
        if(typeof name !== 'string' || typeof callback !== 'function') return this;
        let ary = this.events[name] || (this.events[name] = []);
        if(ary.some(obj => obj.callback === callback)) return this;
        ary.push({callback});
        return this;
      }
    }
    
    let observer = new Observer();
    function testHandler(){}
    observer.on('test', testHandler)
      .on('test', testHandler);
      
    console.log(observer.events);

    【讨论】:

      猜你喜欢
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 2022-11-03
      • 1970-01-01
      • 2018-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多