繁体   English   中英

防止多次绑定功能

[英]Prevent binding a function more than once

我有一个递归重试例程,如下所示:

Foo.prototype.retry = function(data, cb){

   cb && (cb = cb.bind(this));  // want to bind the cb fn just once

   this.resolutions[x] = (err, val) => {

      if(val === 'foobar'){
        // in this case, we do a retry
        return this.retry(data, cb);
      }

   }:

}

如您所见,在某些情况下,我将再次调用this.run重试。 但是我想避免cb.bind()调用cb.bind() 有什么好办法吗?

=>我的意思是什么,有没有办法以某种方式检查被绑定到特定的函数this价值?

我知道的唯一好的解决方案是传递一个重试计数,如下所示:

 Foo.prototype.retry = function(data, cb){

       if(cb){
         if(!data.__retryCount){
             cb = cb.bind(this);
         }
       }

       this.resolutions[x] = (err, val) => {

          if(val === 'foobar'){
            // we do a retry here
            data.__retryCount = data.__retryCount || 0;
            data.__retryCount++;
            return this.retry(data, cb);
          }

       }:

    }

您可以对绑定版本使用局部变量,以便在递归调用自己时传递原始cb ,而不是绑定的cb

Foo.prototype.run = function(data, cb){

   let callback = (cb && cb.bind(this)) || function() {};

   this.resolutions[x] = (err, val) => {
      if(val === 'foobar'){
        // we do a retry here and pass original cb
        return this.run(data, cb);
      }
   };

   // then elsewhere in this function when you want to use the bound one, use callback()
}

或者,如果您确实只想绑定一次,则可以在包装函数中执行此操作,并通过一个假定回调已绑定的子函数递归调用自己:

// internal function, assumes callback is already bound
Foo.prototype._run = function(data, cb){
    // cb is already bound here
    this.resolutions[x] = (err, val) => {
        if(val === 'foobar'){
        // we do a retry here
            return this._run(data, cb);
        }
   }

}

// bind the callback and then call our internal function
Foo.prototype.run = function(data, cb){
   let callback = (cb && cb.bind(this)) || function() {};
   return this._run(data, callback);
}

您可以创建一个类变量,以指示该函数是否已绑定:

 let Foo = function() { this.resolutions = []; }; Foo.prototype.run = function(data, cb) { if (!this.bound) { console.log('binding'); cb && (cb = cb.bind(this)); this.bound = true; } this.resolutions[x] = (err, val) => { if (val === 'foobar') { // we do a retry here return this.run(data, cb); } }; }; console.log('x'); let x = new Foo(); x.run(); console.log('y'); let y = new Foo(); y.run(); console.log('x'); x.run(); 

由于绑定使Function.toString()方法的原始纯文本函数源代码模糊不清,因此您可以检查字符串版本以查看是否已绑定用户界面函数:

 if(!/\[native code\]/.test(cb)) cb = cb.bind(this);

请注意,您不能在本机方法(例如console.logwindow.alert上使用此方法,但这对您的用例而言可能不是问题。

整体上:

 Foo.prototype.retry = function(data, cb){
   if(!/\[native code\]/.test(cb)) cb = cb.bind(this); //  bind the cb fn just once
   this.resolutions[x] = (err, val) => {
      if(val === 'foobar'){
        // in this case, we do a retry
        return this.retry(data, cb);
      }
   }
};

暂无
暂无

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

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