Recursive Ajax deferred object

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();
});

Answers


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


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 condition

  • to 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.


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();
    }

Need Your Help

Wrapping Lua code in Python on Raspberry Pi

python shell lua wrapper raspberry-pi3

I am using Raspberry Pi model 3 and run my scripts on Raspbian Jessie.

jQuery Validation PlugIn : Callback for field success validation?

jquery jquery-plugins jquery-validate

Im am using errorPlacement to add a class to a label to show a graphic element in addition to the error text ( they are both different elements).