簡體   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