0

I needed to create a script, which is sending post requests (data in array) continuously to server and getting responses, but I also need to make delays (for about 3-5 seconds) between every 5th or 6th iteration. As example:

1st data
2nd data
3rd data
4th data
5th data
** 5sec. delay - wait here**
6th data
7th data
...etc...

Sending and receiving data is OK, but I can't correctly implement setTimeout in my code to be fully working as I need.

Big thanks to everyone, who will be able to fix this code.

<!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>
3
  • If you want continuous requests why not just use setInterval? Commented Aug 2, 2016 at 16:57
  • Possible duplicate of setTimeout() method inside a while loop Commented Aug 2, 2016 at 16:57
  • How could look that solution with setInterval, please? I have no other idea at this point how to solve my problem... Commented Aug 2, 2016 at 17:07

3 Answers 3

5

You probably want to use setInterval() or you have to recursivly call setTimeout()

(function func() {
    //do your upload
    setTimeout(func, 3);
})();

with bind you can pass parameters:

(function func(i) {
    //do your upload
    setTimeout(func.bind(this, i), 3);
})();
Sign up to request clarification or add additional context in comments.

2 Comments

Could you show me that solution with setInterval, please? Tried this, but still no delays (all requests sent immediatelly after clicked button)
var interval = setInterval(function() { func(i--); if(!i) clearInterval(interval); }, 3); You don't need the while loop then
2

This is a fully working example. See the comments and watch the log output to understand how it ticks, it's pretty self-explanatory.

<!DOCTYPE html>
<html>
    <body>
        <h2>AJAX</h2>
        <button type="button" onclick="loadDoc()">Request data</button>
        <p id="demo">Loading...</p>
        <script>
            function loadDoc() {

                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 pendingRequests = 0; // how many requests are waiting for a response\
                var htmlBuffer = []; // best practice to build your html before inserting to save memory

                // instead of using the closure inside the loop, just use a regular function
                // this way you're not duplicating the code and you're keeping the logic clean
                var makeRequest = function(i){
                    console.log("making a request");
                    var xhttp = new XMLHttpRequest();
                    xhttp.onreadystatechange = function () {                
                        if (xhttp.readyState == 4 && xhttp.status == 200) {

                            //. add to the buffer
                            htmlBuffer.push(code[i]+":   "+xhttp.responseText);
                            pendingRequests--;
                            console.log("request is back. "+pendingRequests+" requests still pending.");


                            if(pendingRequests===0){
                                // if there are no pending requests
                                if(i==0){
                                    // if there are no more codes to send, put the thml in the dom
                                    document.getElementById("demo").innerHTML = htmlBuffer.join('<br>');
                                }else{
                                    // else wait 3 seconds and send the next 5 requests
                                    console.log("waiting 3 seconds... "+i+" codes still need to be sent.");
                                    setTimeout(doFiveRequests, 3000);
                                }
                            }
                        }
                    };
                    xhttp.open("POST", "https://www.example.com/services/postdata.svc", true);
                    xhttp.setRequestHeader("Host", "www.example.com");
                    xhttp.setRequestHeader("Accept", "application/json, text/javascript");
                    xhttp.setRequestHeader("Accept-Language", "cs,en-US;q=0.7,en;q=0.3");
                    xhttp.setRequestHeader("Accept-Encoding", "gzip, deflate, br");
                    xhttp.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                    xhttp.setRequestHeader("Cache-Control", "no-cache");
                    xhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
                    xhttp.setRequestHeader("Referer", "https://www.example.com/postdata-test.htm");
                    xhttp.setRequestHeader("Content-Length", "37");
                    xhttp.setRequestHeader("Connection", "keep-alive");
                    xhttp.send('{"code":"' + code[i] + '","confirm":false}');
                    pendingRequests++;
                };

                // this function just calls the next 5 requests
                var doFiveRequests = function(){
                    // make next 5 requests
                    for(var n=i-5; i>n&&i>-1; i--){
                        makeRequest(i);
                    }
                };

                // start the loop...
                doFiveRequests();

            } // end function
        </script>
    </body>
</html>

Comments

1

This is because of the way you are calling your are calling the setTimeout function

By calling the setTimeout function in the following way

setTimeout(func(i), k);

You are actually assigning the result of funct(i) as the callback for your setTimeout

you should call the setTimeout like so

setTimeout(func.bind(this, i), k);

Which will call the func function with the current this context bound to it, with the current i variable

2 Comments

Well, I replaced my setTimeout.. line with yours (that second one), but still all requests are sent immediatelly to server, no delays as I need. Any other solution please? I have completely no idea at this point.
@FilipCZ that might be because of your if statement where you are checking if p == 5 (which is i think where you use the setTimeout), and you are adding aswell p from within the func, as within the else statement, maybe you should debug how many times you actually hit your code where you do the setTimeout

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.