【问题标题】:JavaScript: setTimeout doesn't pause the loopJavaScript:setTimeout 不会暂停循环
【发布时间】:2016-08-01 16:10:56
【问题描述】:

我需要在我的循环中进行一些延迟,每次在一定数量的数据(通过我的循环的几个周期/迭代之后)发送到服务器之后。

发送数据和接收来自服务器的响应工作正常,但请求的循环延迟仍然不起作用。

非常感谢您的帮助。

编辑:代码已更改,请检查第三个答案(我的)。

<!DOCTYPE html>
<html>
<body>

<h2>AJAX</h2>

<button type="button" onclick="loadDoc()">Request data</button>

<p id="demo"></p>

<script>
function loadDoc() {
    var xhttp = [];



    var code = [
"WOICEL0Q9P",
"ZJTS4GYJEJ",
"HJPMQOCX31",
"MP26N0BH01",
"7TJNYZIRJR",
"Z5MIDDG4N2",
"BX6MKYK0O7",
"KVFVH1ESQX",
"40ADY3ZBE5",
"V4NT360JR5",
"FDI8AFL680",
"ZH89N59XQR",
"M6OS2OX38H",
"D8O76YDLM0",
"86GBMJLIXY",
"1QRFVU26VK",
"HFUI9QV6DY",
"VN83OGR825",
"DDMPCBX2MF",
"2M3QFPI234"
    ];

    var i = code.length;
    var j = code.length;
    var k = 5000;

    var p = 0;


    while (i--) {
        var process = (function(i) {
            if (p == 5) {
                p = 0;
                function func(i) {
                    xhttp[i] = new XMLHttpRequest();
                    xhttp[i].onreadystatechange = function() {
                        if (xhttp[i].readyState == 4 && xhttp[i].status == 200) {
                            if (i == j) {
                                document.getElementById("demo").innerHTML = code[i] + ":   " + xhttp[i].responseText;
                            }
                            else {
                                document.getElementById("demo").innerHTML += "<br><br>" + code[i] + ":   " + xhttp[i].responseText;
                            }
                        }
                    };
                    xhttp[i].open("POST", "https://www.example.com/services/postdata.svc", true);
                    xhttp[i].setRequestHeader("Host", "www.example.com");
                    xhttp[i].setRequestHeader("Accept", "application/json, text/javascript");
                    xhttp[i].setRequestHeader("Accept-Language", "cs,en-US;q=0.7,en;q=0.3");
                    xhttp[i].setRequestHeader("Accept-Encoding", "gzip, deflate, br");
                    xhttp[i].setRequestHeader("Content-Type", "application/json; charset=utf-8");
                    xhttp[i].setRequestHeader("Cache-Control", "no-cache");
                    xhttp[i].setRequestHeader("X-Requested-With", "XMLHttpRequest");
                    xhttp[i].setRequestHeader("Referer", "https://www.example.com/postdata-test.htm");
                    xhttp[i].setRequestHeader("Content-Length", "37");
                    xhttp[i].setRequestHeader("Connection", "keep-alive");
                    xhttp[i].send('{"code":"'+code[i]+'","confirm":false}');
                    //console.log('hello - Test if delay is here');
                    p++;
                }
                setTimeout(func(i), k);
                k += 5000;
            }
            else {
                xhttp[i] = new XMLHttpRequest();
                xhttp[i].onreadystatechange = function() {
                    if (xhttp[i].readyState == 4 && xhttp[i].status == 200) {
                        if (i == j) {
                            document.getElementById("demo").innerHTML = code[i] + ":   " + xhttp[i].responseText;
                        }
                        else {
                            document.getElementById("demo").innerHTML += "<br><br>" + code[i] + ":   " + xhttp[i].responseText;
                        }
                    }
                };
                xhttp[i].open("POST", "https://www.example.com/services/postdata.svc", true);
                xhttp[i].setRequestHeader("Host", "www.example.com");
                xhttp[i].setRequestHeader("Accept", "application/json, text/javascript");
                xhttp[i].setRequestHeader("Accept-Language", "cs,en-US;q=0.7,en;q=0.3");
                xhttp[i].setRequestHeader("Accept-Encoding", "gzip, deflate, br");
                xhttp[i].setRequestHeader("Content-Type", "application/json; charset=utf-8");
                xhttp[i].setRequestHeader("Cache-Control", "no-cache");
                xhttp[i].setRequestHeader("X-Requested-With", "XMLHttpRequest");
                xhttp[i].setRequestHeader("Referer", "https://www.example.com/postdata-test.htm");
                xhttp[i].setRequestHeader("Content-Length", "37");
                xhttp[i].setRequestHeader("Connection", "keep-alive");
                xhttp[i].send('{"code":"'+code[i]+'","confirm":false}');
                p++;
            }
        })(i);
    }
}
</script>

</body>
</html>

【问题讨论】:

    标签: javascript delay settimeout


    【解决方案1】:

    您会立即在while 中不断产生对process() 的多个调用,然后告诉process 在该回调发生之前等待5 秒。

    // Run this loop over and over again
    while (true) {
        // Create a function called process that process data
        var process = (function () {
            // Do something with data
            console.log("Something");
            // Wait a few seconds and do it again
            setTimeout(process, 5000);
        // This () right here says call process right now
        }());
    }
    

    【讨论】:

    • 感谢您的帮助,但我可以请您更正我的代码吗?我仍然没有太多 JavaScript 编程经验。
    • 我在你发布的代码中修复了括号,我只是保持递减的while循环,但脚本现在不起作用。我在控制台中收到此错误:未捕获的类型错误:无法读取未定义的属性 'readyState'
    【解决方案2】:

    当您运行代码时,while 循环不会等待 setTimeout,因为它是异步的。

    但您可以执行以下操作以使您的代码正常工作。

    var p = 0;
    var k = 0;
    var now = new Date();
    var code = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
    for (var index = 0; index < code.length; index++) {
        (function(idx, timeout){
            setTimeout(function(i) {
                //write your code herei
                console.log("printed after", (new Date() - now)/1000, " Seconds");
    
            }, timeout, idx);
            p++;
            if(p==5){
                p = 0;
                k += 5000;
            }
        })(index, k);
    }
    

    下面是输出

    printed after 0.006  Seconds
    printed after 0.008  Seconds
    printed after 0.008  Seconds
    printed after 0.008  Seconds
    printed after 0.008  Seconds
    printed after 5.008  Seconds
    printed after 5.008  Seconds
    printed after 5.008  Seconds
    printed after 5.008  Seconds
    printed after 5.008  Seconds
    printed after 10.007  Seconds
    printed after 10.007  Seconds
    printed after 10.007  Seconds
    printed after 10.007  Seconds
    printed after 10.007  Seconds
    printed after 15.008  Seconds
    printed after 15.008  Seconds
    printed after 15.008  Seconds
    printed after 15.008  Seconds
    printed after 15.008  Seconds
    

    【讨论】:

    • 谢谢 suraj,我会立即检查您的代码。
    • 编辑:好吧,它只是缺少 k 的定义,但是您的脚本仍然不能按我的需要工作。在循环 5 个周期后,必须有一个延迟,这不在您的代码中。顺便说一句,感谢您的努力。不起作用,未捕获的 ReferenceError:未定义 k
    • 你到底想做什么?连续打五个电话然后等待5秒然后再打五个连续电话等等?或者只有每五个呼叫应该延迟 5 秒
    • 编辑2:好吧,每次我在预设延迟发布请求发送到服务器后单击按钮,我都可以看到响应。但是我需要该脚本自动生成并通过循环发送请求,并且在例如 5 个循环之后 - 放置一个小的延迟。但请求必须自动发送,而不是在单击按钮后发送。
    • 我无法测试我的解决方案,因为您没有分享实际网址,但仍然jsfiddle.net/xvLb54mL从此链接复制代码并粘贴我认为它会工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-12
    • 2014-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多