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

IT技术 javascript jquery ajax json polling
2021-03-18 17:16:33

我是一个初级到中级的 JavaScript/jQuery 程序员,因此非常感谢具体/可执行的示例。

我的项目需要使用 AJAX 轮询一个 URL,该 URL 返回包含要添加到 DOM 的内容的 JSON,或者消息{ "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个回答

您可以使用简单的超时来递归调用 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
  }
}

除非您想发出警报或其他什么,否则您不需要在错误函数中执行任何操作。它错误的简单事实将阻止成功函数被调用并可能触发另一个轮询。

setTimeout() 是否会在延迟期间阻止脚本其余部分的执行?
2021-04-22 17:16:33
No.setTimeout()指定将来要执行的代码块的某个时间间隔。脚本的其余部分只会在超时到期并且代码运行时被阻止。
2021-04-24 17:16:33
“在短循环中,最好只执行 setTimeout 以给它一些喘息空间。在某些时候,您可能会使用 setInterval() 每 50 毫秒轮询一次函数,或者其他什么。在这种情况下,可能没有足够的时间来完成您正在尝试做的事情,然后再做一次。” - 来源
2021-05-15 17:16:33

非常感谢您的功能。它有点问题,但这里是修复程序。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 作为参数,然后一切都很好;-)

干杯尼克

在我的头顶:

$(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 的解决方案在我的情况下效果更好 - 不过这很有用。
2021-05-12 17:16:33

您可以使用 javascript setInterval 函数每隔 5 秒加载一次内容。

var auto= $('#content'), refreshed_content; 
    refreshed_content = setInterval(function(){
    auto.fadeOut('slow').load("result.php).fadeIn("slow");}, 
    3000);

供你参考-

每 3 秒自动刷新 div 内容