【问题标题】:jQuery, simple polling examplejQuery,简单的轮询示例
【发布时间】:2011-10-13 17:32:46
【问题描述】:

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

我熟悉如何在 jQuery 中执行 AJAX,但我似乎无法找到让它在“计时器”上执行的“正确”方式。

【问题讨论】:

    标签: jquery polling


    【解决方案1】:
    function doPoll(){
        $.post('ajax/test.html', function(data) {
            alert(data);  // process results here
            setTimeout(doPoll,5000);
        });
    }
    

    【讨论】:

    • 有些人用过setTimeout,有些人用过setInterval。为什么一个人比另一个人更受欢迎?
    • setinterval 无论如何都会每 5 秒进行一次 ajax 调用。编写它的方式(我认为这是很好的做法)将等待结果然后在 5 秒后发出另一个 ajax 请求。有时我会使用 setinterval,但这不是其中之一。在我们得到上一个请求的结果之前,我们不应该提出任何新的请求
    • 请注意,如果单个请求失败,建议的代码将停止轮询。在典型情况下,您可能仍希望继续轮询。我不会在 成功处理程序 中使用setTimeout,而是使用jQuery always 链接ajax 调用。像这样:$.post('ajax/test.html') .done(function(data) { /* process */ }) .always(function() { setTimeout(doPoll, 5000); });
    • 没有尾调用优化。这只会不断增加函数调用堆栈。建议使用蹦床图案。
    • @BoopathiRajaa 请提供此类蹦床模式的示例。
    【解决方案2】:

    这是一个使用 jQuery 的(archive.org 镜像)helpful article on long polling(长期持有的 HTTP 请求)。本文衍生的一个代码sn-p:

    (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
        })
    })();
    

    【讨论】:

    • 有没有办法取消轮询,或者发出信号停止?
    • 如果从服务器获得预期结果,如何清除超时?
    • 你可以像下面的例子一样清除超时: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); } })();
    • 不要点击上面的 techoctave.com 链接。试图做各种讨厌的事情
    【解决方案3】:

    来自 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 解决方案!
    • 是什么让它成为 ES6 解决方案 Boopathi Rajaa, setInterval()?
    【解决方案4】:
    function poll(){
        $("ajax.php", function(data){
            //do stuff  
        }); 
    }
    
    setInterval(function(){ poll(); }, 5000);
    

    【讨论】:

    • 注意:你可以使用这个语法setInterval(poll, 5000);
    【解决方案5】:
    function make_call()
    {
      // do the request
    
      setTimeout(function(){ 
        make_call();
      }, 5000);
    }
    
    $(document).ready(function() {
      make_call();
    });
    

    【讨论】:

      【解决方案6】:

      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
          }
      

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

      • 如果您不希望 then() 立即失效,回调应该返回另一个 thenable 对象(可能是另一个 Deferred),sleep 和 ajax 行都这样做。
      • 其他人都不好意思承认。 :)

      【讨论】:

      • 类似的答案在:Deferred in a while loop
      • 我的“迭代递归”评论可能有点误导。这里没有实际的递归,因为“递归”调用发生在匿名回调中——在initiate_polling 运行完成之后。
      • 在最新的浏览器中,您不再需要 jQuery 来执行此操作——请在此处查看我的答案:stackoverflow.com/a/48728503/86967
      • 纯 JavaScript 超时:new Promise( resolve => setTimeout(resolve,1000) ).then( () => alert("done") )
      • 异步递归是迭代
      【解决方案7】:

      这个解决方案:

      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()
      })
      

      【讨论】:

        【解决方案8】:
        (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);
        })();
        

        【讨论】:

          【解决方案9】:

          我为此创建了一个小型 JQuery 插件。你可以试试:

          $.poll('http://my/url', 100, (xhr, status, data) => {
              return data.hello === 'world';
          })
          

          https://www.npmjs.com/package/jquerypoll

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-03-14
            • 2015-10-13
            • 2010-12-10
            • 2018-04-11
            • 2011-10-12
            • 2017-03-11
            • 2014-10-10
            • 1970-01-01
            相关资源
            最近更新 更多