简体   繁体   中英

Asynchronous JavaScript polling freezes the browser using setTimeout or setInterval

I write a polling script to receive newly created data records. I want to execute the call in every N seconds.

I tried setTimeout() and setInterval() to run the polling asynchronously , but both freeze the browser while executing the Polling() function, which is really strange for me.

I call the StarPolling() function when the page is loaded. APICall() function is a jQuery $.POST function which is working well - and async - in any other situations.

This is the code I use with setTimeout()

var pollinginterval = 5000;
function StartPolling()
{
    setTimeout(Polling, pollinginterval);
}

function Polling()
{
    [... some code ...]

    var api_call = 'API_URL';
    var api_call_parameters = {
        [...]
    };
    APICall(api_call, api_call_parameters, function(json_response)
    {
        /* this is the callback belongs to the $.POST request */

        [... some code ...]

        setTimeout(Polling, pollinginterval);
    });
}

The version I tried using setInterval() is very similar except the recursive call.

I can not use Workers or HTML5 sockets for this because cross-browser support is a must.

Is there any way to run the polling in a REAL asynchronous way , or using a new 'thread' with JavaScript without freezing the browser?

UPDATE: This is how the APICall() operates:

function APICall(call, parameters, success_callback)
{
    $.post(apibase + "" + call,parameters)
    .done(function(response){
        try
        {
            var json_response = $.parseJSON(response);
        }
        catch(error)
        {
            [...]
        }

        if(json_response.header.status == "OK")
        {
            success_callback(json_response);
        }
        else if(json_response.header.status == "error")
        {
            [...]
        }
    })
    .fail(function(error) {
        [...]
    });
}

UPDATE : I am testing the polling with a normal and private browser (firefox) window at the same time to try the functionality. I just noticed, that the problem only occurs when both windows are running the polling simultaneously.

Maybe it is a firefox bug...

The OP is wanting to run Polling in such a way that it doesn't interfere with the main thread (ie in a background thread). The only way to do this is to use a WebWorker, which he specifically doesn't want to use.

For a bunch of interesting reading see the W3 document about event loops , but basically everything that happens in the browser is single threaded. All javascript will happen on the main thread (except for web workers). All setTimeout and setInterval do is queue a callback that will get run in the main thread after ~x seconds.

So sorry, there isn't any other way beside web workers.

You may use a long polling pattern like this :

(function Polling() {
    setTimeout(function() {
        $.ajax({ url: "server", success: function(response) {
            //your try/catch here
        }, dataType: "json", complete: Polling });
    }, 5000);
})();

So the poll will attempt to finish before to restart, even if the server job is quite long...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM