不断轮询$.ajax请求问题

Continuously polling $.ajax request issue

我在连续轮询 $.ajax 请求时遇到问题。我要 运行 解决的问题是如何让它先立即执行,然后在 setTimeout 调用中设置的时间间隔内执行。

代码示例:

http://jsbin.com/doneka/3/

myObj = {};

var output = '';
var items = '';
myObj.displayItems = function() {
 console.log('displayItems ran');
 output = '';
 $.each(items, function(index, val) {
   output += '<li>' + val.player.firstName + ' ' + val.player.lastName + '</li>';
 });
 $('#content').html(output);

};

$(document).ready(function() {
 (function loadData() {
 setTimeout(function() {
  console.log('loadData ran....');
  return  $.ajax({
   url: '//jsbin.com/xinixa/1.json',
   type: 'GET',
   dataType: 'json',
   cache: false,
   success: function(data) {
    items = data.apiResults[0].league.season.draft.rounds[0].picks;
    loadData();
    myObj.displayItems();
   },
  });
 }, 3000);
 })();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="content"></div>
</body>
</html>

每当我重构以在函数内部调用 setTimeout 时,都会出现错误。如果我让函数不能自动执行,我也会出错。

我不确定您是否按照我的理解在此处使用 "refactor",但是重构您的代码将对诊断问题有很大帮助。像您这样的深度嵌套函数很少是必需的,而且几乎总是令人困惑。这是一个快速而肮脏的重构,用于删除嵌套。我不确定它是否真正实现了您的目标,但它确实连续无误地执行。 DEMO:

var myObj = {};
var output = '';
var items = '';

myObj.displayItems = function() {
  console.log('displayItems ran');
  output = '';
  $.each(items, function(index, val) {
    output += '<li>' + val.player.firstName + ' ' + val.player.lastName + '</li>';
  });
  $('#content').html(output);

};

var loadData = function() {
  setTimeout(makeAjaxRequest, 3000);
};

var makeAjaxRequest = function() {
  console.log('makeAjaxRequest running');
  return    $.ajax({
    url: '//jsbin.com/xinixa/1.json',
    type: 'GET',
    dataType: 'json',
    cache: false,
    success: successHandler,
  });
};

var successHandler = function(data) {
  items = data.apiResults[0].league.season.draft.rounds[0].picks;
  loadData();
  myObj.displayItems();
};

$(document).ready(loadData);

还有几个需要改进的地方:

  • 删除 outputitems 中的全局保存状态。 output 可以很容易地重构为 myObj 对象的状态,并且 items 应该是 displayItems() 函数的参数。

  • 当你这样做的时候,重命名 myObj :)

  • 我不确定 setTimeout 是否是这里使用的正确函数;如果你真的想要每 3 秒重复一次的内容,为什么不使用 setInterval 呢?

如果我对你的理解正确,那么这应该对你有用。看看吧here

myObj = {};

var output = '';
var items = '';
myObj.displayItems = function () {
    console.log('displayItems ran');
    output = '';
    $.each(items, function (index, val) {
        output += '<li>' + val.player.firstName + ' ' + val.player.lastName + '</li>';
    });
    $('#content').html(output);
};

$(document).ready(function () {
    (function loadData() {
        console.log('loadData ran....');
        $.ajax({
            url: '//jsbin.com/xinixa/1.json',
            type: 'GET',
            dataType: 'json',
            cache: false,
            success: function (data) {
                items = data.apiResults[0].league.season.draft.rounds[0].picks;
                myObj.displayItems();
                setTimeout(loadData, 10000);
            },
        });
    })();
});

我唯一更改的部分是您的 loadData 函数。该方法仍然立即调用,但我将 window.setTimeout() 移到了成功回调中(我将超时更改为 10s 以进行测试)。这会在上一个有效设置轮询的成功回调之后设置超时。

如果你看控制台,你可以看到 loadData() 立即执行,每个后续调用在上一个调用后 10 秒执行。

希望这对您有所帮助。如果还有什么可以帮到您的,请告诉我。