2014-02-27 55 views
1

我有一個名爲'succeeder'的自制函數,它應該嘗試運行一個名爲'func'的函數,並且它在間隔後嘗試再次運行它。setTimeout之後,這會丟失上下文

這是第一次,當setTimeout後第二次調用func時,它工作的很好,它失敗了,這似乎沒有上下文。

你能想到這段代碼中不正確的東西嗎?

succeeder({ 
    func : function() { 
     !this.dbOpen && this.init(); 
     return true; 
    }, 
    context : this, 
    interval : 2000, 
    success : function() { return true;} 
}); 

function succeeder(opts) { 
    function run() {   
     try {   
      //_.delay(function(){opts.func();}.bind(opts.context), 2000); 
      setTimeout(function(){ return _.bind(opts.func, opts.context)(); }, 2000); 
     } catch (e) { 
      run(this.opts, this.interval); 
     }  
    } 
    run();  
}; 

感謝

+0

I * *疑這條線可以做不同的事情第二次運行:'this.dbOpen && this.init();'...也不知道是什麼'this.opts,this.interval! '是指在捕獲?兩者都顯得「未定義」。 – Carpetsmoker

+0

這些是我忽略刪除的原始代碼的一部分,但實際上這是有缺陷的行,但不是因爲它是未定義的,它是,因爲這會丟失其上下文 –

回答

0

您的代碼不會做這樣的事情的描述。此外,描述不清楚:「如果它[func]失敗」是什麼意思? func是否會拋出異常?返回false?或者是什麼?

沒有代碼檢查來自func的返回值,但示例版本func返回truetrue返回值的目的是什麼?

你有一個try/catch塊,這讓我懷疑你在談論func調用引發異常。但是這個try/catch不會發現func拋出的任何異常!

這是因爲try/catch正在包裝setTimeout呼叫。但func不是從該try/catch塊內部調用的。這叫做後面的,當超時觸發,try/catch在那時不再有效。

什麼是opts.success函數?它從未被使用過。

此外,代碼在第一次嘗試呼叫func之前總是需要兩秒鐘的延遲時間。你想要嗎?還是你希望第一個電話是立即的,只有在通話失敗並且你重試的時候纔會延遲?

下面是一個工作示例,它可以處理您正在談論的內容。我假定「失敗」意味着「拋出異常」,並且您不希望在初始func調用上有任何延遲。

爲了測試我使用一個運行倒計時,每一次拋出異常,最後當倒數到0

與調試控制檯運行這個開放的,所以你可以看到console.log()成功的消息一func函數的代碼:

function Test() { 
    this.countdown = 5; 

    succeeder({ 
     func: function() { 
      console.log(
       this.constructor.name, 
       'countdown:', 
       this.countdown 
      ); 
      if(this.countdown--) { 
       console.log('func throwing error'); 
       throw new Error('fail'); 
      } 
      console.log('func success!'); 
     }, 
     context: this, 
     interval: 1000, 
     success: function() { return true; } 
    }); 
}; 

new Test; 

function succeeder(opts) { 
    var func = _.bind(opts.func, opts.context); 
    function run() { 
     try {   
      func(); 
     } catch (e) { 
      setTimeout(run, opts.interval); 
     }  
    } 
    run();  
}; 
+1

感謝您的全面解答和代碼更正,真的很有幫助。 –