使用jQuery AJAX轮询JSON响应,根据AJAX结果或JSON内容进行处理

46

我是一名初中级JavaScript/jQuery程序员,因此需要具体/可执行的示例。

我的项目要求使用AJAX轮询一个返回JSON的URL,其中包含要添加到DOM的内容或消息{ "status" : "pending" },表示后端仍在生成带有内容的JSON响应。想法是第一个对URL的请求会触发后端开始构建JSON响应(然后进行缓存),随后的调用将检查此JSON是否准备就绪(如果准备好,则提供)。

在我的脚本中,我需要以15秒间隔轮询此URL,最多达到1:30分钟,并执行以下操作:

  • 如果AJAX请求导致错误,请终止脚本。
  • 如果AJAX请求成功,且JSON内容包含{ "status" : "pending" },则继续轮询。
  • 如果AJAX请求成功,且JSON内容包含可用内容(即任何有效响应,而不仅仅是{ "status" : "pending" }),则显示该内容,停止轮询并终止脚本。

我尝试了一些方法,但只有有限的成功,但我感觉它们都比必要的要麻烦。这是一个骨架函数,我已经成功地使用它来一次制作单个AJAX请求,如果我从JSON响应中获取了可用内容,则完成其工作:

// make the AJAX request
function ajax_request() {
  $.ajax({
    url: JSON_URL, // JSON_URL is a global variable
    dataType: 'json',
    error: function(xhr_data) {
      // terminate the script
    },
    success: function(xhr_data) {
      if (xhr_data.status == 'pending') {
        // continue polling
      } else {
        success(xhr_data);
      }
    },
    contentType: 'application/json'
  });
}

然而,该函数目前除非收到包含可用内容的有效JSON响应,否则不会执行任何操作。

关于那些只是注释的行,我不确定该怎么做。我猜想另一个函数应该处理轮询,并在需要时调用ajax_request(),但我不知道ajax_request()以最优雅的方式将其结果传递回轮询函数,以便它可以适当地响应。

非常感谢任何帮助!如果我能提供更多信息,请告诉我。谢谢!

4个回答

47
你可以使用一个简单的超时(timeout)来递归调用ajax_request。
success: function(xhr_data) {
  console.log(xhr_data);
  if (xhr_data.status == 'pending') {
    setTimeout(function() { ajax_request(); }, 15000); // wait 15 seconds than call ajax request again
  } else {
    success(xhr_data);
  }
}

在那行代码周围放置一个计数器检查,你就能得到最大投票数。

if (xhr_data.status == 'pending') {
  if (cnt < 6) {
    cnt++;
    setTimeout(function() { ajax_request(); }, 15000); // wait 15 seconds than call ajax request again
  }
}

除非您想要弹出警报或类似的操作,否则在错误函数中无需执行任何操作。因为产生错误将阻止调用成功函数并可能触发另一个轮询。


1
setTimeout()在延迟期间是否会阻塞其余脚本的执行? - abc def foo bar
1
setTimeout()指定了未来一段时间内要执行的代码块。只有当超时到期并且代码运行时,脚本的其余部分才会被阻塞。 - Joel
在短循环中,最好使用setTimeout来给它一些休息时间。在某些情况下,您可能会使用setInterval()每隔50毫秒轮询一个函数。在这种情况下,可能没有足够的时间来完成您尝试做的事情,然后再次执行。 - PHearst

4
非常感谢这个函数。虽然有一点小问题,但是这里有解决方案。roosteronacid的答案在达到100%后没有停止,因为clearInterval函数的使用出现了错误。
这是一个可行的函数:
$(function ()
{
    var statusElement = $("#status");

    // this function will run each 1000 ms until stopped with clearInterval()
    var i = setInterval(function ()
    {
        $.ajax(
        {
            success: function (json)
            {
                // progress from 1-100
                statusElement.text(json.progress + "%");

                // when the worker process is done (reached 100%), stop execution
                if (json.progress == 100) clearInterval(i);
            },

            error: function ()
            {
                // on error, stop execution
                clearInterval(i);
            }
        });
    }, 1000);
});

clearInterval()函数将间隔ID作为参数,然后一切都很好;-)
祝福 尼克

3

就我个人而言,

$(function ()
{
    // reference cache to speed up the process of querying for the status element
    var statusElement = $("#status");

    // this function will run each 1000 ms until stopped with clearInterval()
    var i = setInterval(function ()
    {
        $.ajax(
        {
            success: function (json)
            {
                // progress from 1-100
                statusElement.text(json.progress + "%");

                // when the worker process is done (reached 100%), stop execution
                if (json.progress == 100) i.clearInterval();
            },

            error: function ()
            {
                // on error, stop execution
                i.clearInterval();
            }
        });
    }, 1000);
});

谢谢回复!我发现Joel Potter的解决方案在我的情况下更有效 - 不过这也很有用。 - Bungle

0
你可以使用JavaScript的setInterval函数每5秒钟加载一次内容。
var auto= $('#content'), refreshed_content; 
    refreshed_content = setInterval(function(){
    auto.fadeOut('slow').load("result.php).fadeIn("slow");}, 
    3000);

供您参考-

每3秒自动刷新div内容


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接