【问题标题】:How to avoid discontinuity in periodical HTTP request by jQuery?如何避免 jQuery 定期 HTTP 请求的不连续性?
【发布时间】:2013-01-08 21:41:47
【问题描述】:

我是 jQuery 新手,想用它每 3 秒从服务器检索一次数据。 Web 服务器每 3 秒以 JSON 格式发送数据。 JSON 数据包含一个数值数组字段 { "samples" : [10,15,-7,19,34,...] }。我编写了以下 jQuery ajax 请求,每 3 秒从服务器检索一次数据:

function getData() {
    $.ajax({
        url : 'http://example.com',
        type: 'GET',
        success : function(data) {
            myData = data.samples;
            setTimeout(getData, 3000);
        },
        dataType : 'json'
    });

    return myData;
}

但是,由于时间抖动,从服务器发送的数据可能不会每 3 秒准确更新一次。那么我应该如何编写 jQuery ajax 请求以避免可能的数据不连续性呢?也就是说,我希望返回的 myData 包含来自每个 getData() 调用的所有新数据数组元素,并且不包含由于可能的时序抖动而导致的重复或丢失的数据样本。

【问题讨论】:

  • 你有什么数据可以唯一标识你的原子数据吗?这样,您可以发送最后检索到的数据的 id,并让服务器从下一个开始发送。
  • “定时抖动”是指你发出请求时服务器上的数据可能刷新稍慢或正在刷新?
  • 否 没有从服务器发送的时间戳信息。通过“时间抖动”,任何情况都可能发生:服务器可能刷新稍慢于 3 秒,或者在您发出请求时正在刷新。

标签: ajax http jquery


【解决方案1】:

将数据在服务器上更新的最后一个时间戳与另一个 JSON 数组一起发送。然后,当需要使用您的 jQuery 调用再次请求数据时,请检查时间戳与您已有的时间戳。这将为您提供一种方法来了解它是否是相同的数据,或者它是否已被刷新。

【讨论】:

  • 如果服务器没有为最近一次刷新发送任何时间戳信息,客户端有没有办法做到这一点?
  • @tonga 并非没有某种方式可以唯一地标识返回的信息集,正如 Andre 上面提到的那样。
【解决方案2】:

我认为您可能需要传递更多信息。在您的 AJAX 中包含另一个名为“lastUpdate”的字段,并带有时间戳。您的 javascript 可以保存它获得的最后一个时间戳并将其提供给服务器。服务器仅响应该时间戳之后的样本(因此您不会错过任何样本),并且如果它仍然是最新的,则不会响应任何内容(因此您不会重复)。

【讨论】:

  • 那么这是否意味着不改变服务器端就无法做到这一点?
【解决方案3】:

返回myData 没什么意义。 (a) 变量未在函数内声明,(b) 数据从服务器异步到达。

就目前而言,getData() 被保证(最多)返回在上一次迭代中获得的数据。

要使用新获得的数据,您需要在success 函数或done() 回调中对myData 执行任何必要的操作,如下所示:

function getData() {
    $.ajax({
        url: 'http://example.com',
        type: 'GET',
        dataType : 'json'
    }).done(function(data) {
        var myData = data.samples;
        //Do whatever is necessary with myData here.
        //Call extenal function as necessary to do the job.
        setTimeout(getData, 3000);
    });
}

【讨论】:

  • 我忘记了 myData 在我原来的帖子中是本地的。
  • myData 的范围有点学术性。关键是,你不能从getData() 返回它,就好像一切都是同步的。
  • 如果我从函数 getData() 中返回 myData ,为什么它返回之前获得的数据,而不是最新的数据?假设我以下列方式使用 a = getData(); “a”会是我从轮询服务器中获得的最新数据数组吗?抱歉我不熟悉Ajax的机制。
  • “AJAX”的第一个“A”代表“异步”,这意味着发出 HTTP 请求的代码在继续执行下一条语句之前不会等待 HTTP 响应 - 在您的代码中下一条语句将是return myData。服务器响应将在 稍后 后到达;那时success(或done)函数将被触发。所以语句的执行顺序并不是它们在函数中出现的顺序。如果您仍然不明白,请阅读同步代码和异步代码之间的区别,尤其是 AJAX。
  • 非常感谢您的解释。
【解决方案4】:

以利用 ajax 的异步特性的方式编写代码。例如,

var interval;
function handleData(data) {
    // I handle the data returned from the ajax request.
    console.log(data);
}
function getData() {
    // I send the ajax request.
    $.ajax({
        url: 'http://example.com',
        success: handleData,
        error: function(){
            // on error, stop making requests to help with debugging.
            console.log(arguments);
            clearInterval(interval);
        }
    });
}
interval = setInterval(getData,3000);

这将导致在大多数情况下,响应将按顺序排列。如果您摆脱了间隔,而是在上一次成功后 3 秒调用 get data,那么您可以在所有情况下都做到这一点。

function getData() {
    // I send the ajax request.
    $.ajax({
        url: 'http://example.com',
        success: handleData,
        error: function(){
            // on error, stop making requests to help with debugging.
            console.log(arguments);
        }
    });
}
function handleData(data) {
    // I handle the data returned from the ajax request.
    console.log(data);
    setTimeout(getData,3000);
}
getData();

旁注:“时序抖动”根本不是抖动,它只是一个逻辑错误。由于 Ajax 是异步的,数据总是落后一组。

【讨论】:

  • 感谢指正。 “时间抖动”是指我不想在两个 Ajax 请求之间丢失或重复样本。我从 JSON 获得延迟数组很好,但没有丢失或重复的样本。根据以上回复,看来我需要在服务器端以 JSON 格式添加一些信息。
  • @tonga 你不需要添加任何额外的信息,如果错误回调永远不会被调用,你就不会错过任何响应。只有当服务器本身返回重复时才会发生重复,您不会从一个请求中得到两个响应。
  • @KevinB 我相信这里的实际问题是服务器端可能会返回重复项。你的例子是一个很好的例子,除了这个问题之外的一般实施。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-15
  • 2014-05-12
相关资源
最近更新 更多