在 For 循环中延迟 jQuery Ajax

Delay jQuery Ajax in For loop

我无法在循环中的 ajax 请求之间进行延迟。 我希望脚本等待 7 秒来执行下一个。请求不相同,我不知道其中有多少。

$(document).ready(function () {
    var announce = $("#announce").data('id');
    var lots_cnt = parseInt($("#announce").data('lotscnt'));
    for (var i = 0; i < Math.ceil(lots_cnt/20); i++) {
        $.ajax({
                method: "GET",
                url: "/project/lots/"+announce+"/"+(i+1),
                async: false,
                beforeSend: function () {
                    $("#console").append("<strong>Parsing lots from page "+(i+1)+"...</strong><br/>");
                },
                complete:function(){

                },
                success: function (m) {
                    $("#console").append(m);
                    addprogressstep();
                    setTimeout(function() { $("#console").append("Waiting 7 sec ...<br/>"); }, 7000);
                },
                error:function(jqXHR,  textStatus,  errorThrown){

                }
            });
    };

});

这是一个很棒的问题!

我看到您正在使用 jQuery.ajax。根据 jQuery documentation$.get() 现在 returns 一个承诺。我们可以用承诺来实现你想要的。

首先,在你的 for 循环中,for (var i = 0; i < Math.ceil(lots_cnt/20); i++) {,你做的第一件事是 运行 $.ajax。相反,我们要做的是构建一个函数数组,其中每个函数returns一个承诺。

var funcArray = [];
// EDIT changed var i to let i
for (let i = 0; i < Math.ceil(lots_cnt/20); i++) {
    var getFunction = function(){
        var getPromise = $.get(...);
        return getPromise;
    }
    funcArray.push(getFunction);
}

然后,您将编写一个递归(大概)函数来处理每个函数,当前一个函数完成时(如果您愿意,可以在超时后)

function runNext(){
    if (funcArray.length > 0) {
        var nextFunction = funcArray.shift();
        nextFunction() // this is our $.get promise
            .then(function(resultOfGet){
                // do something with your result
                setTimeout(runNext,1000*7);
            })
    }
}

runNext();

--- 编辑 --- 以下是将 $.ajax 变成承诺的方法:

function ajx(i) {
    return new Promise(function(resolve, reject){
        $.ajax({
            method: "GET",
            url: "/project/lots/"+announce+"/"+(i+1),
            async: false,
            beforeSend: function () {
                $("#console").append("<strong>Parsing lots from page "+(i+1)+"...</strong><br/>");
            },
            complete:function(){

            },
            success: function (m) {
                $("#console").append(m);
                addprogressstep();
                resolve(m);
            },
            error:function(jqXHR,  textStatus,  errorThrown){
                reject(jqXHR,  textStatus,  errorThrown);
            }
        });
    })    
}

您可以使用 map 而不是 for 来修复。

如果使用地图,您可以更改异步设置true

在处理异步处理时,最好使用map而不是for语句。