异步JavaScript轮询使用setTimeout或setInterval

时间:2015-08-14 14:18:42

标签: javascript jquery ajax asynchronous polling

我编写了一个轮询脚本来接收新创建的数据记录。我想在每N秒内执行一次调用。

我尝试setTimeout()setInterval()运行轮询异步,但两者都在执行Polling()功能时冻结浏览器,这对我来说真的很奇怪

我在加载页面时调用StarPolling()函数。 APICall()函数是jQuery $.POST函数,在任何其他情况下运行良好 - 并且异步 - 。

这是我与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()的版本与递归调用非常相似。

我不能使用Workers或HTML5套接字,因为必须使用跨浏览器支持。

有没有办法以 REAL异步方式运行轮询,或者使用带有JavaScript的新线程' 而不冻结浏览器?

更新 这就是APICall()的运作方式:

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 :我正在使用普通和私有浏览器(firefox)窗口同时测试轮询以尝试该功能。我只是注意到,只有当两个窗口同时运行轮询时才会出现问题。

也许这是一个火狐虫......

2 个答案:

答案 0 :(得分:0)

OP希望以不干扰主线程(即后台线程)的方式运行Polling。唯一的方法是使用WebWorker,他特别不想使用它。

对于一堆有趣的阅读,请参阅关于event loops的W3文档,但基本上浏览器中发生的一切都是单线程的。所有javascript都将在主线程上发生(除了Web worker)。所有setTimeoutsetInterval都会对一个回调进行排队,该回调将在~x秒后在主线程中运行。

很抱歉,除了网络工作者之外没有任何其他方式。

答案 1 :(得分:-1)

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

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

因此,即使服务器作业很长,轮询也会尝试在重新启动之前完成...