问题
I need to paste some data in the DOM when a recursive ajax function ends its recursion.
The problem I have is that "$.when().done()" will trigger in the first step of rescursion but I need that it triggers on the last step of recursion, when recursion ends.
I really have no idea how to achive it, any help will be kindly apreciated!
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();
});
回答1:
You can use deffered.promise
object to handle recursive execution. I've modified your example to provide some data and stop condition. Example here -> jsfiddle
回答2:
The key is to doing this concisely (and arguably simply) is :
to use an outer member for your data, rather than trying to pass it through
to build a
.then()
chain in the recursion, using the success path to recurse and the fail path for the terminal conditionto ensure that the php script will eventually return an HTTP error, thus avoiding infinite recursion.
Recursive function :
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);
}
Call as follows :
var data = {'whatever':'whatever'};//this is the outer member
recursiveFunction().fail(paintData);
No .when()
and no messy counters.
See FIDDLE, which, for demonstration, uses a setTimeout in place of $.ajax()
and an array as the outer member.
回答3:
If you plan to use typescript you can do as below
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();
}
来源:https://stackoverflow.com/questions/21649668/recursive-ajax-deferred-object