找到你要的答案

Q:Asynchronous JavaScript polling freezes the browser using setTimeout or setInterval

Q:异步JavaScript轮询使用setTimeout和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...

我写了一个轮询脚本来接收新创建的数据记录。我想在每n秒执行呼叫。

我试着settimeout()和setinterval()运行轮询异步,但冻结浏览器在执行polling()功能,这真是奇怪的我。

我叫starpolling()函数在页面加载。apicall()函数是一个jQuery。后功能运转良好,在任何其他情况下异步。

这是我用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);
    });
}

我试着用setinterval()非常相似的递归调用。

我不能用工人或HTML5插座因为跨浏览器的支持是必须的。

有什么方法可以在一个真正的异步方式运行查询,或使用一个新的线程的JavaScript不冻结浏览器吗?

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) {
        [...]
    });
}

更新:我正在测试的投票与正常和私人浏览器(Firefox)的窗口在同一时间尝试功能。我注意到,只有当两个窗口同时运行轮询时,问题才会出现。

也许这是一个火狐bug…

answer1: 回答1:

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.

OP是希望运行轮询的方式,它不干扰主线程(即在背景线程)。要做到这一点的唯一方法是使用webworker,他特别不想用。

一堆有趣的阅读看到事件循环的W3的文件,但基本上都是在浏览器是单线程的。所有的JavaScript将在主线程发生(除网络工作者)。所有的setTimeout和setInterval回调做队列将~ X秒后在主线程中运行。

很抱歉,网络工作者没有其他的方法。

answer2: 回答2:

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

您可以使用这样的长轮询模式:

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

因此,即使服务器工作相当长,轮询也会尝试在重新启动之前完成…

javascript  jquery  ajax  asynchronous  polling