2013-01-05 93 views
1

我有以下代碼:如何在上一篇文章完成後運行代碼?

for (var i = 0; i < numFiles; i++) { 
    $.post('/Secure/File/PhysicalFileHandler.ashx?custId=whatever&idx=' + i, function (data) { 
     ids += data + '|'; 
     if (i == numFiles-1) { 
      ids = ids.substring(0, ids.length - 1); 
     } 
    }); 

} 

我怎麼能執行一個代碼塊中的最後一個職位完成後?我上面嘗試的方法不起作用(i==numFiles已經到達那裏了)。建議?

回答

2

這是一個比較常見的問題 - 您所引用的「i」是由for函數處理的,通常for函數在回調觸發時完成執行(在這種情況下,「i」是等於numFiles已經)。有一對夫婦的解決方案,這樣的:一個是改變回調到這一點:

(function (i) { 
    return function (data) { 
    ids += data + '|'; 
    if (i == numFiles-1) { 
     ids = ids.substring(0, ids.length - 1); 
    } 
})(i) 

這樣做是什麼創造了循環的​​每次執行一個新的功能,每個功能都有時間它自己的參考「我」 - 而不是回到for循環的定義/值的i,它有它自己的本地參數來引用。這必須通過返回另一個函數來完成,因爲您需要在for循環的第一遍期間執行代碼,以確保在觸發回調時保留正確的值。

另一種替代方法是將整個post語句包裝在一個函數中,並使用它自己的副本 - 我認爲兩者之間沒有太大的區別。就我個人而言,我更喜歡上面代碼片段中的方法,因爲它最大限度地減少了代碼整體流程的影響,但意見會因此而有所不同。

0

帖子可能無法按照它們開始的順序完成。你必須對每一個都進行計數,以確定所有結束。

var finishedCount = 0; // track number of calls finished 
for (var i = 0; i < numFiles; i++) { 
    (function(i) { 
     $.post('/Secure/File/PhysicalFileHandler.ashx?custId=whatever&idx=' + i, function (data) { 
      ids += data + '|'; 
      finishedCount = finishedCount + 1; // increment number of calls finished 
      if (finishedCount == numFiles) { // run only when all calls have finished 
       ids = ids.substring(0, ids.length - 1); 
      } 
     }); 
    })(i); // capture value of i in closure 
} 

編輯:在封閉捕捉我的價值不再是必要的,因爲我沒有在這個版本後回調函數中使用。

相關問題