2014-02-19 76 views
0

我已經實現了一個ajax輪詢函數,我需要連續調用,直到輪詢結果返回我的預期結果。爲了達到這個目的,我使用setTimeout來引入一個延遲,以便該函數不會在服務器上發出請求,直到獲得結果爲止。setTimeout出現意外的行爲

讓我通過說我已經找到了我需要實現代碼以獲得所需的預期行爲的方式。但是,我的問題是關於我找到的解決方案。我想知道爲什麼解決方案正常工作,而另一個沒有。

這裏是工作的代碼,設置成功後的結果超時和民意測驗:

function makeRequest(url, data, requestType, successCallback, errorCallback, doneCallback) { 
    $.ajax({ 
     url: url, 
     type: requestType, 
     data: data != null ? JSON.stringify(data) : '', 
     contentType: 'application/json; charset=utf-8', 
     success: function (success) { 
      if (successCallback) successCallback(success); 
     }, 
     error: function (error) { 
      if (errorCallback) errorCallback(error); 
     }, 
     done: function() { 
      if (doneCallback) doneCallback(); 
     } 
    }); 
} 

function pollForResult(Id) { 
    setTimeout(function() { 
     makeRequest('/Transaction/TransactionResult/' + Id, 
      null, 
      "GET", 
      function(result) { 
       //success code here 
      }, function(error) { 
       //error callback implementation here 
       if (error.status === 404) { 
        pollForResult(Id); //results not ready, poll again. 
       } else { 
        alert("stopped polling due to error"); 
       } 
      }, null); 
    }, 2000); 
} 

這是不正確設置超時,只是不斷的代碼與命中請求的服務器:

function pollForResult(Id) { 
    makeRequest('/Transaction/TransactionResult/' + Id, 
     null, 
     "GET", 
     function(result) { 
      //success code here 
     }, function(error) { 
      //error callback implementation here 
      if (error.status === 404) { 
       setTimeout(pollForResult(Id), 2000); //results not ready, poll again. 
      } else { 
       alert("stopped polling due to error"); 
      } 
     }, null); 
} 

所以,我的問題是這樣的:第二塊代碼是什麼讓它不斷輪詢服務器的結果,而不是等待2秒再次輪詢?

我懷疑,雖然我沒有試過,這將在代碼的第二塊正常工作:

setTimeout(function(){ pollForResult(Id); }, 2000); //results not ready, poll again. 

回答

3
setTimeout(pollForResult(transactionId),2000); 

此代碼立即電話pollForResult,並指定其返回值是發生超時時調用的函數。

這是所需的行爲,因爲您可能有一個函數構建閉包並將其傳遞給超時。但它似乎趕出了很多人...

正如你所說,function() {pollForResult(transactionId);}將工作得很好。

+0

+1,你也可以使用[Function.prototype.bind()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind):' setTimeout(pollForResult.bind(null,transactionId),2000);'如果你喜歡更短的語法。 (注意:如果您不使用[polyfill](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Compatibility),它需要IE 9+。 – ComFreek

+1

@ComFreek原因是工作是因爲'.bind()'*返回一個函數(閉包)^ _ ^ –

相關問題