jQuery,简单的轮询示例


105

我正在学习jQuery,并试图找到一个简单的代码示例,该示例将轮询API以查找条件。(即每隔几秒钟请求一个网页并处理结果)

我熟悉如何在jQuery中执行AJAX,我似乎似乎找不到找到使其在“计时器”上执行的“正确”方法。

Answers:


140
function doPoll(){
    $.post('ajax/test.html', function(data) {
        alert(data);  // process results here
        setTimeout(doPoll,5000);
    });
}

4
有些人用过setTimeout,有些用过setInterval。为什么一个人比另一个人偏爱?
迈克,

36
无论如何,setinterval都会每5秒发出一次Ajax调用。编写方式(我认为这是一种很好的做法)将等待结果,然后在5秒钟后再次发出ajax请求。有时我会使用setinterval,但这不是其中之一。在获得上一个请求的结果之前,我们不应该发出任何新请求
Johnny Craig

107
请注意,如果单个请求失败,建议的代码将停止轮询。在典型情况下,您可能仍想继续轮询。我不会setTimeout成功处理程序内使用,而是始终将ajax调用与jQuery链接在一起。像这样的: $.post('ajax/test.html') .done(function(data) { /* process */ }) .always(function() { setTimeout(doPoll, 5000); });
貂Wikström

6
没有尾注优化。这只会继续增加函数调用堆栈。建议使用蹦床模式。
Boopathi Rajaa

8
@BoopathiRajaa,请提供此类蹦床模式的示例。
2015年

60

这是有关使用jQuery 进行长期轮询(长期HTTP请求)的有用文章。从本文派生的代码段:

(function poll() {
    setTimeout(function() {
        $.ajax({
            url: "/server/api/function",
            type: "GET",
            success: function(data) {
                console.log("polling");
            },
            dataType: "json",
            complete: poll,
            timeout: 2000
        })
    }, 5000);
})();

仅在ajax请求完成后,才发出下一个请求。

上面的一种变体,在遵守等待/超时间隔之前,将在首次调用它时立即执行。

(function poll() {
    $.ajax({
        url: "/server/api/function",
        type: "GET",
        success: function(data) {
            console.log("polling");
        },
        dataType: "json",
        complete: setTimeout(function() {poll()}, 5000),
        timeout: 2000
    })
})();

有没有办法取消轮询或发出停止信号?
塔尔

如果从服务器获得了预期结果,如何清除超时?
abhishek77in

您可以像下面的示例一样清除超时:let is_success = false; (function poll() { let timeout = setTimeout(function() { $.ajax({ url: resp.location, type: "GET", success: function(data) { if(YOUR_CONDITION) { is_success=true; } }, dataType: "json", complete: poll, timeout: 2000 }) }, 5000); if(is_success) { console.log("ending poll"); window.clearTimeout(timeout); } })();
Marius

2
不要单击上面的techoctave.com链接。尝试做各种令人讨厌的事情
Siddharth Ram

13

从ES6,

var co = require('co');
var $ = require('jQuery');

// because jquery doesn't support Promises/A+ spec
function ajax(opts) {
  return new Promise(function(resolve, reject) {
    $.extend(opts, {
      success: resolve,
      error: reject
    });
    $.ajax(opts);
  }
}

var poll = function() {
  co(function *() {
    return yield ajax({
      url: '/my-api',
      type: 'json',
      method: 'post'
    });
  }).then(function(response) {
    console.log(response);
  }).catch(function(err) {
    console.log(err);
  });
};

setInterval(poll, 5000);
  • 不使用递归(函数堆栈不受影响)。
  • 在需要对setTimeout-recursion进行尾调用优化的情况下,不会受到影响。

很高兴看到ES6解决方案!
PHearst 2015年

是什么使它成为ES6解决方案Boopathi Rajaa,setInterval()?
哈利尔

11
function poll(){
    $("ajax.php", function(data){
        //do stuff  
    }); 
}

setInterval(function(){ poll(); }, 5000);

3
注意:您可以使用此语法setInterval(poll, 5000);
R3tep '17

7
function make_call()
{
  // do the request

  setTimeout(function(){ 
    make_call();
  }, 5000);
}

$(document).ready(function() {
  make_call();
});

2

jQuery.Deferred()可以简化异步排序和错误处理的管理。

polling_active = true // set false to interrupt polling

function initiate_polling()
    {
    $.Deferred().resolve() // optional boilerplate providing the initial 'then()'
    .then( () => $.Deferred( d=>setTimeout(()=>d.resolve(),5000) ) ) // sleep
    .then( () => $.get('/my-api') ) // initiate AJAX
    .then( response =>
        {
        if ( JSON.parse(response).my_result == my_target ) polling_active = false
        if ( ...unhappy... ) return $.Deferred().reject("unhappy") // abort
        if ( polling_active ) initiate_polling() // iterative recursion
        })
    .fail( r => { polling_active=false, alert('failed: '+r) } ) // report errors
    }

这是一种优雅的方法,但是有一些陷阱...

  • 如果您不希望a then()立即失败,则回调函数应返回另一个thenable对象(可能是another Deferred),sleep和ajax行都这样做。
  • 其他人则太尴尬而不能承认。:)

类似的答案在:延迟循环
Brent Bradburn

我的“迭代递归”评论可能有点误导。这里没有实际的递归,因为“递归”调用是从匿名回调发生的-在initiate_polling运行完成之前。
布伦特·布拉德本

在最新的浏览器中,您不再需要jQuery做到这一点-在这里查看我的答案:stackoverflow.com/a/48728503/86967
Brent Bradburn,

纯JavaScript超时:new Promise( resolve => setTimeout(resolve,1000) ).then( () => alert("done") )
Brent Bradburn

异步递归是迭代
Brent Bradburn '18

0
(function poll() {
    setTimeout(function() {
        //
        var search = {}
        search["ssn"] = "831-33-6049";
        search["first"] = "Harve";
        search["last"] = "Veum";
        search["gender"] = "M";
        search["street"] = "5017 Ottis Tunnel Apt. 176";
        search["city"] = "Shamrock";
        search["state"] = "OK";
        search["zip"] = "74068";
        search["lat"] = "35.9124";
        search["long"] = "-96.578";
        search["city_pop"] = "111";
        search["job"] = "Higher education careers adviser";
        search["dob"] = "1995-08-14";
        search["acct_num"] = "11220423";
        search["profile"] = "millenials.json";
        search["transnum"] = "9999999";
        search["transdate"] = $("#datepicker").val();
        search["category"] = $("#category").val();
        search["amt"] = $("#amt").val();
        search["row_key"] = "831-33-6049_9999999";



        $.ajax({
            type : "POST",
            headers : {
                contentType : "application/json"
            },
            contentType : "application/json",
            url : "/stream_more",
            data : JSON.stringify(search),
            dataType : 'json',
            complete : poll,
            cache : false,
            timeout : 600000,
            success : function(data) {
                //
                //alert('jax')
                console.log("SUCCESS : ", data);
                //$("#btn-search").prop("disabled", false);
                // $('#feedback').html("");
                for (var i = 0; i < data.length; i++) {
                    //
                    $('#feedback').prepend(
                            '<tr><td>' + data[i].ssn + '</td><td>'
                                    + data[i].transdate + '</td><td>'
                                    + data[i].category + '</td><td>'
                                    + data[i].amt + '</td><td>'
                                    + data[i].purch_prob + '</td><td>'
                                    + data[i].offer + '</td></tr>').html();
                }

            },
            error : function(e) {
                //alert("error" + e);

                var json = "<h4>Ajax Response</h4><pre>" + e.responseText
                        + "</pre>";
                $('#feedback').html(json);

                console.log("ERROR : ", e);
                $("#btn-search").prop("disabled", false);

            }
        });

    }, 3000);
})();


0

此解决方案:

  1. 有超时
  2. 错误响应后也可以进行轮询

jQuery的最低版本为1.12

$(document).ready(function () {
  function poll () {
    $.get({
      url: '/api/stream/',
      success: function (data) {
        console.log(data)
      },
      timeout: 10000                    // == 10 seconds timeout
    }).always(function () {
      setTimeout(poll, 30000)           // == 30 seconds polling period
    })
  }

  // start polling
  poll()
})
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.