2014-02-08 34 views
0

當遞歸ajax函數結束遞歸時,我需要將一些數據粘貼到DOM中。遞歸Ajax延遲對象

我遇到的問題是「$ .when()。done()」會在第一步的遞歸中觸發,但我需要在遞歸結束時觸發遞歸的最後一步。

我真的不知道如何找到它,任何幫助都會好心的貶低!

function recursiveFunction(data) { 

    // do something with data 
    // and remove elements processed from data 

    var param = { 
      "data" : data 
    }; 
    return $.ajax({ 
      data: param, 
      url: 'script.php', 
      type: 'post', 
      success: function(response) { 
       recursiveFunction(response); 
      }, 
    }); 
} 

$.when(recursiveFunction(data)).done(function(response){ 
    paintData(); 
}); 

回答

2

您可以使用deffered.promise對象來處理遞歸執行。我修改了您的示例以提供一些數據和停止條件。例如在這裏 - >jsfiddle

+0

它的工作原理就像一個魅力! – user3287601

1

關鍵是要簡潔(而且可能僅僅)這樣做是:

  • 使用外部部件爲您的數據,而不是試圖通過

  • 將它傳遞

    在遞歸中構建一個.then()鏈,使用成功路徑進行遞歸,併爲終端條件創建失敗路徑

  • 確保PHP腳本最終會返回HTTP錯誤,從而避免無限遞歸。

遞歸函數:

function recursiveFunction(response) { 
    if(response) { 
     // use `response` to act on the outer object `data` 
    } 
    return $.ajax({ 
     url: 'script.php', 
     type: 'post', 
     data: { 
      "data" : data 
     } 
    }).then(recursiveFunction); 
} 

電話如下:

var data = {'whatever':'whatever'};//this is the outer member 
recursiveFunction().fail(paintData); 

沒有.when(),沒有凌亂的櫃檯。

參見FIDDLE,其中,用於演示,使用代替$.ajax()一個setTimeout和數組作爲外部構件。

+0

我需要.when(),因爲我在等待2個延遲對象 – user3287601

+2

不,'.when()'用於解析兩個或多個* parallel * promise。你有兩個*順序*的承諾。你的第二個'.ajax()'是在第一個成功之後創建的。 –

+0

非常好,我一直在尋找一個能夠完成你所描述的功能:_sequential_ Ajax調用。我正在搜索一個非常大的數據庫(數百萬行),發現我可以通過分塊請求來提高UX和加載時間。這導致_N_/_n_(_N_:總行數,_n_:每個塊的行數)ajax調用。如果這些調用是並行發送的,則這與_N_行的一個請求相同 - 這就解決了該解決方法。謝謝甜菜根 - 甜菜根! – seebiscuit

0

如果你打算使用打字稿,你可以做如下

private updateDataNextLink(nextLinkAddress: string, outputAddress: string, defer?: JQueryDeferred<any>): JQueryPromise<string> {    
     if (defer){ 
      defer = $.Deferred();   
     } 

     DataService.retrieveSkipTokenData1(nextLinkAddress).done((tagData) => { 
      let tableData: any = ServiceContainer.officeApiHelper.createExcelTableFormat(tagData); 
      ServiceContainer.officeApi.addData(outputAddress, [], tableData.rows).done((address) => { 
       if (tagData['odata.nextLink']) { 
        ServiceContainer.officeApi.getOffsetCell(tableData.rows.length, 0, address).done((offsetAddress) => { 
         App.Instance.updateDataNextLink(tagData['odata.nextLink'], offsetAddress, defer); 
        }); 
       } else { 
        defer.resolve(address); 
       }; 
      }); 
     }); 

     return defer.promise(); 
    }