1

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...

Patartics Milán
  • 4,858
  • 4
  • 26
  • 32
  • 5
    What exactly does `APICall` do? That's where the problem is. Is it doing synchronous AJAX? – Pointy Aug 14 '15 at 14:21
  • @Pointy It could, but unlikely since it has a callback? Maybe it supports both? – Ruan Mendes Aug 14 '15 at 14:23
  • I updated my question with the APICall function – Patartics Milán Aug 14 '15 at 14:26
  • 1
    Have you profiled your application? – Bergi Aug 14 '15 at 14:29
  • 2
    If I were were you; first I shall do is to remove ajax call in APICall method and just put a console.log and see if browser is still hanging from repeated interval call..... – Akki619 Aug 14 '15 at 14:29
  • maybe you can use a `web worker` doing the xhr request (http://stackoverflow.com/questions/20663353/is-it-feasible-to-do-an-ajax-request-from-a-web-worker) – Philipp Dahse Aug 14 '15 at 14:29
  • 1
    Maybe it's something in the [ ... some code ...] part before calling APIcall() – Paul Aug 14 '15 at 14:29
  • 1
    I don't see anything in your code that would freeze the browser. – Kevin B Aug 14 '15 at 14:39
  • 1
    Unless the returns JSON is huge or the code that processes the returned JSON takes a long time to run or something is overriding Ajax calls to make them synchronous, I don't see how this code freezes the browser. Can you demonstrate the issue in a jsFiddle so we can do our own debugging on it. – jfriend00 Aug 14 '15 at 14:40
  • @PatarticsMilán Just to clarify: `Polling` is supposed to run synchronously, while the AJAX request is supposed to happen asynchronously. Right? – JosiahDaniels Aug 14 '15 at 14:42
  • FYI, you can run the Ajax code in a webWorker and process the result there and then just message the result back to the main thread where it can be inserted into the DOM. If the processing is truly taking a long time, this would move all that work out of the main thread and into its own thread. – jfriend00 Aug 14 '15 at 14:45
  • @Paul The first 'some code' generates the parameters for the call, and the second one updates some elements – Patartics Milán Aug 14 '15 at 14:46
  • @JosiahDaniels Polling() should run async. – Patartics Milán Aug 14 '15 at 14:47
  • @PatarticsMilán This might help: http://stackoverflow.com/questions/19626680/is-settimeout-a-good-solution-to-do-async-functions-with-javascript – JosiahDaniels Aug 14 '15 at 14:49
  • Can you reproduce this in a jsfiddle? – slebetman Aug 14 '15 at 14:50
  • The problem is likely here: `[... some code ...]` – Kevin B Aug 14 '15 at 14:51
  • Have you tried removing the APIcall and leaving it's setInterval to see if it is the APICall causing the problem or the other codes? If it works, then maybe take out [ .. some code .. ] in the call back and see what happens – Paul Aug 14 '15 at 15:00
  • Just added a second update, it seems like the problem is because of the browser. Any way thank you guys! – Patartics Milán Aug 14 '15 at 15:09

2 Answers2

0

The OP is wanting to run Polling in such a way that it doesn't interfere with the main thread (i.e. 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.

JosiahDaniels
  • 2,411
  • 20
  • 37
-1

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...

Karbos 538
  • 2,977
  • 1
  • 23
  • 34
  • Right, but what's wrong with his current pattern? why would it be freezing the browser? – Kevin B Aug 14 '15 at 14:38
  • Maybe in the server side... it will make a request every 5 seconds even if the server job is not finished. – Karbos 538 Aug 14 '15 at 14:41
  • but that would just stop the requests, it wouldn't freeze the browser. – Kevin B Aug 14 '15 at 14:42
  • 2
    This is already similar to the OP's current pattern so this does not answer the question. The only difference I see is that the OP stops on errors and your code keeps going on errors. So how does this answer the question? – jfriend00 Aug 14 '15 at 14:42
  • @Karbos Right, which wouldn't have any effect on the "freezes my browser" problem. – Kevin B Aug 14 '15 at 14:49
  • I think the "freezes my browser" problem comes from too much request, but maybe I'm wrong... See the @Akki619 suggestion first... – Karbos 538 Aug 14 '15 at 14:54