Search code examples
javascriptdelayexecution

Need to call function after pausing execution


I have a scenario in which I am going to display news at a bottom bar in a web page. I am calling a cgi script which will return the news as a string array of 4 elements max, at an interval of 10 seconds.

After receiving the array of news items, I am updating the bottom bar on every 2 seconds displaying 1 news item at time. this is my code :

 function listenForNews(){   
    var xmlHttpReq = getXMLHttpReq();   
    var destinationURL = cgi+"/news.cgi";
    if (xmlHttpReq.readyState == 0){
        xmlHttpReq.open('GET', destinationURL, true);
        xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlHttpReq.onreadystatechange = function() {
            if (xmlHttpReq.readyState == 4) {
                if(xmlHttpReq.responseText != ""){
                    updateNews(xmlHttpReq.responseText);
                    t=setTimeout("listenForNews();",10000);
                }
            }
        }
        xmlHttpReq.send();
    }   
}

  //Pause JS execution for 2 seconds to display 1 item at a time
    function pause(ms) {    
        ms += new Date().getTime();
        while (new Date() < ms){}
    }
    //update text field after 2 sec
    function updateNews(buffer){
        for(var i=0;i<buffer.length;i++){
            document.getElementById('text').value = buffer[i] + " at "+ new Date();
            pause(2000);
        }
}

But the problem I am facing is I am not able to get exactly same scenario as I expect. Actually the cgi call is itself delaying for more than 20 seconds each time (10 sec * 2 sec).

So on GUI, text filed is updated after approx 20 sec. What I want is textfield should be updated every 2 sec as well as cgi call should be made on every 10 sec(with synchronized way)

Is it possible to achieve this?


Solution

  • A pause function like that will hang the browser, preventing it from redrawing the page. Thus, nothing will appear to happen until that loop over i ends. There are two simple ways to do this involving setTimeouts:

    function updateNews(buffer, i)
    {
        document.getElementById('text').value = buffer[i] + " at "+ new Date();
        if(i + 1 < buffer.length)
            setTimeout(function() {updateNews(buffer, i+1);}, 2000);
    }
    

    which would be called by updateNews(xmlHttpReq.responseText, 0);. This chains the calls by having each one create the timeout for the next one.

    function updateNews(buffer)
    {
        var i;
        for(i = 0;i < buffer.length;i++)
            setTimeout(function() {document.getElementById('text').value = buffer[i] + " at "+ new Date();}, 2000 * i);
    }
    

    This one sets all of the timeouts at the beginning, using different lengths of time to space them out.