递归Ajax延迟对象

时间:2014-02-08 17:57:47

标签: jquery ajax deferred

当递归ajax函数结束递归时,我需要在DOM中粘贴一些数据。

我遇到的问题是" $。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();
});

3 个答案:

答案 0 :(得分:3)

您可以使用deffered.promise对象来处理递归执行。我已修改您的示例以提供一些数据并停止条件。这里的例子 - > jsfiddle

答案 1 :(得分: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 ,为了演示,它使用setTimeout代替$.ajax(),并使用数组作为外部成员。

答案 2 :(得分: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();
    }