0

我需要帮助弄清楚如何在为函数保留“str”的同时设置间隔。

客户端选择一个选项,函数“GET”是选定的选项。但是当它在 setInterval 中刷新时,它会丢失字符串。我该怎么做?

我试过这个:

<script type="text/javascript">
function countrystats(str)
  {
  if (str=="")
  {
  document.getElementById("countrystats").innerHTML="";

  return;
  } 
  if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
  else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
  xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
  {
  document.getElementById("countrystats").innerHTML=xmlhttp.responseText;
  }
  }
  xmlhttp.open("GET","countrystats.php?q="+str,true);
  xmlhttp.send();

 setInterval(countrystats, 5000);


  }
  </script>

希望你能帮我解决这个烂摊子:-)

我知道这可以用一些 jQuery 来完成,但我似乎可以让它工作。也许这两件事是相关的,我不知道:-)

以下是函数 countrystats 获取输入的方式:

script type="text/javascript">
$("#countrystats_menu > li > a").click(function (ev) {
  var str = $(this).html();
  countrystats(str);

  $('#country_span').html(str);
  });


  </script>

编辑/解决方案:

似乎问题在于,在执行 setInterval 时,它丢失了附加的 str,但是这段代码保留了它。

setTimeout((function(strPriorToTimeout)
{//IIFE's scope preserves state of str variable
    return function()
    {
        countrystats(strPriorToTimeout);
    };
})(str),5000);
4

3 回答 3

0

我已经用 jQuery 简化了你的代码。我使用jQuery.load将远程 html 加载到起始元素。

并且每当单击一个新项目时,您都需要创建上一个间隔,否则将运行多个请求线程

function countrystats(str) {
    if (str == "") {
        $('#countrystats').empty();
        return;
    }

    $('#countrystats').load('countrystats.php?q=' + str)

}

var interval;
$("#countrystats_menu > li > a").click(function(ev) {
    if (interval) {
        clearInterval(interval);
    }

    var str = $(this).html();

    countrystats(str);
    interval = setInterval(function() {
                countrystats(str);
            }, 5000);

    $('#country_span').html(str);
});
于 2013-03-01T10:51:14.003 回答
0

参数str最后超出范围,间隔只是调用函数而不将任何值传递给str. 正如一些评论所暗示的那样,countrystats(str)似乎可以解决问题,但事实并非如此,原因如下:

setInterval(countrystats(str), 500);

此行包含多个表达式,这些表达式被评估/解析为某个值,例如countrystats(str),这是对函数的直接调用。然后,将在设置间隔之前调用该函数。
最快的解决方案是创建一个匿名函数,并从内部调用该函数:

setInterval(function()
{
    countrystats(str);
},5000);

您甚至可以通过创建一个闭包,将预期值实际传递给区间函数来更加安全地发挥它。str这是可选的,可能看起来有点混乱(和混乱):

setInterval((function(strPriorToTimeout)
{//IIFE's scope preserves state of str variable
    return function()
    {
        countrystats(strPriorToTimeout);
    };
})(str),5000);

关于您的代码,只有一件事让我感到困扰:您正在使用setInterval,它每 X 毫秒重复一次相同的函数调用。如果您只需要调用一次函数,则使用setTimeout.
另一件事是:setInterval返回间隔的 id,因此您可以在需要时停止常量函数调用。您似乎没有在任何地方分配该 ID,因此您的代码将继续运行,除非您强制clearInterval调用。也许考虑将返回值分配给setInterval您可以访问的某个变量。
如果您不清除间隔 AFAIK 的唯一方法是:

for (var i=0;i<Number.MAX_VALUE;i++)
{
    clearInterval(i);
}

现在这太可怕了,不是吗?

根据评论,我想我会在这里添加一些关于网络工作者的信息。根据我收集到的 OP 想要实现的目标,我建议尽可能使用网络工作者。这里的基本设置可能是:

//client.js
var worker = new Worker('dashWorker.js');//worker script
//to kick off the worker: 
function countrystats(str)
{
    str = str || document.getElementById('countrystats').innerHTML;//get str value
    worker.postMessage(str);//that's it, the worker takes care of everything else
}
worker.onmessage = function(response)
{
    document.getElementById('countrystats').innerHTML = response.response;//cf worker code
    return countrystats(response.str);//choose when to call the countrystats function again, as soon as the worker responded... easy!
};

//the worker:
self.onmessage = function(e)
{//you could add a way of stopping the constant updates, by posting a 'stopDash' or something...
    //do ajax call using e.data --> this is the string anyhow
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(response)
    {
        if (this.readyState === 4 && this.status === 200)
        {
            self.postMessage({str: e.data, 
                              response: response.responseText});
        }
    };
    xhr.open('GET', 'countrystats.php?q=' + e.data,true);
    xhr.send();
};

当然,这段代码远非“干净”:它可以做一些性能调整(比如不一直查询 DOM),但基本原则是……
这里有几个重要的链接:

MDN
John Resig 关于workers 的博客文章
Webworkers 的逐步介绍

于 2013-03-01T10:47:39.093 回答
0

you are calling setInterval(countrystats, 5000); in the same function. you can do with jquery also

url='countrystats.php?q='+str;

ajax calll

$.get(url, function(data) {
  $('#countrystats').html(data);

});

once the get finishes. you can call setInterval(countrystats, 5000); for refreshing the content.

于 2013-03-01T10:35:12.957 回答