Recursive Ajax deferred object

若如初见. 提交于 2019-12-13 12:50:36

问题


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




回答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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!