【问题标题】:How do I make Ajax calls at intervals without overlap?如何在不重叠的情况下间隔进行 Ajax 调用?
【发布时间】:2009-12-18 22:12:20
【问题描述】:

我希望设置一个网页,该网页通过来自嵌入式网络服务器的 AJAX 调用对数据进行采样。我将如何设置代码以使一个请求不会与另一个请求重叠? 我应该提一下,我几乎没有 JavaScript 经验,并且有一个令人信服的理由不使用任何大小超过 10 KB 左右的外部库。

【问题讨论】:

  • 欢迎来到 StackOverflow。第一个问题很好。

标签: javascript ajax settimeout setinterval


【解决方案1】:

您可能需要考虑仅在上一次 AJAX 调用成功响应后重新启动 AJAX 请求的选项。

function autoUpdate()
{
    var ajaxConnection = new Ext.data.Connection();

    ajaxConnection.request(
    {
        method:         'GET',
        url:            '/web-service/', 

        success: function(response) 
        {
            // Add your logic here for a successful AJAX response.
            // ...
            // ...

            // Relaunch the autoUpdate() function in 5 seconds.
            setTimeout(autoUpdate, 5000);
        }
    }
}

这个例子使用ExtJS,但你可以很容易地只使用XMLHttpRequest

注意:如果您必须有 x 秒的确切时间间隔,则必须跟踪从 AJAX 请求启动到setTimeout() 调用,然后从延迟中减去这个时间跨度。否则,上述示例中的间隔时间将随着网络延迟和处理 Web 服务逻辑的时间而变化。

【讨论】:

  • 不完全是他们的要求,但一个非常好的解决方案(只是使用回调)
  • 好答案。但是,您可能希望在前面的 Ajax 调用完成后setTimeout,无论它是否成功。否则,第一次出现超时或错误时,您将停止获取更新。
【解决方案2】:

我建议你使用像 jx.js (source) 这样的小工具包。你可以在这里找到它:http://www.openjs.com/scripts/jx/(小于 1k 缩小)

设置请求:

jx.load('somepage.php', function(data){
    alert(data); // Do what you want with the 'data' variable.
});

要设置一个间隔,您可以使用setInterval 和一个变量来存储当前是否正在发生请求 - 如果是,我们什么也不做:

var activeRequest = false;
setInterval(function(){

    if (!activeRequest) {
        // Only runs if no request is currently occuring:
        jx.load('somepage.php', function(data){
            activeRequest = false;
            alert(data); // Do what you want with the 'data' variable.
        });
    }
    activeRequest = true;

}, 5000); // Every five seconds

【讨论】:

  • 与其他答案相同...那么为什么要浪费时间间隔,而只是进行同步调用。轮询平均会浪费 5000ms/2。
  • 我知道你的答案了。它可以减少重叠并减少服务器负载。 +
【解决方案3】:

AJAX 虽有名称,但不一定是异步的。

这里是异步方法...

var req;

function ajax(method,url,payload,action)
    {
    if (window.XMLHttpRequest)
        {
        req = new XMLHttpRequest();
        req.onreadystatechange = action;
        req.open(method, url, true);
        req.send(payload);
        }
    else if (window.ActiveXObject)
        {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req)
            {
            req.onreadystatechange = action;
            req.open(method, url, true);
            req.send(payload);
            }
        else
            {
            alert("Could not create ActiveXObject(Microsoft.XMLHTTP)");
            }
        }
    }

...但是这里是一个同步的等价物...

function sjax(method,url,payload,action)
    {
    if (window.XMLHttpRequest)
        {
        req = new XMLHttpRequest();
        req.open(method, url, false);
        req.send(payload);
        action();
        }
    else if (window.ActiveXObject)
        {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req)
            {
            req.onreadystatechange = action;
            req.open(method, url, false);
            req.send(payload);
            }
        else
            {
            alert("Could not create ActiveXObject(Microsoft.XMLHTTP)");
            }
        }
    }

...这是一个典型的动作...

function insertHtml(target)
    {
    var pageTarget = arguments[0];
    if (req.readyState == 4) // 4 == "loaded"
        {
        if (req.status == 200) // 200 == "Ok"
            {
            if (req.responseText.indexOf("error") >= 0)
                {
                alert("Please report the following error...");
                pretty = req.responseText.substring(req.responseText.indexOf("error"),1200);
                pretty = pretty.substring(0,pretty.indexOf("\""));
                alert(pretty + "\n\n" + req.responseText.substring(0,1200));
                }
            else
                {
                div = document.getElementById(pageTarget);
                div.innerHTML = req.responseText;
                dimOff();
                }
            }
        else
            {
            alert("Could not retreive URL:\n" + req.statusText);
            }
        }
    }

【讨论】:

  • 同步请求并不是最好的主意,在我看来,它们也会锁定页面的其余部分......但这取决于用户的要求。另外,来自 jQuery $.ajax 文档:“当需要同步时,最好通过其他方式阻止用户交互。”
猜你喜欢
  • 2022-01-08
  • 2012-01-23
  • 1970-01-01
  • 2017-11-26
  • 2021-12-19
  • 2020-02-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多