ClearInterval无法工作(但有时仅适用于)服务器api调用

时间:2011-08-10 17:32:36

标签: javascript google-chrome google-chrome-extension setinterval

我有这个函数应该每隔4秒查询一次可能已经发布的新内容的数据库。然后我接受返回并使用从服务器返回的任何内容制作的动态html刷新一个feed。这一切都很有效。

我的问题是,作为HTML的一部分,有一个选项托盘,他们可以按下它将滑过部分内容,并给他们不同的选项来处理该内容,删除,复制,评论这样的东西。好吧,当他们弹出托盘我想清除间隔计时器,这样它就不会刷新饲料中的html(使托盘消失)。

另一个问题是用户可以同时打开多个托盘,所以我想出了这个功能来处理它:

function setTimers(status)
{
    var timerGetContent = null;
    if(status == "login")
    {
        tray_count = 0;
        timerGetContent = null;
        timerGetContent = setInterval(getContent,4000);
        alert("inside login");
    }
    else if(status == "negitive")
    {
        tray_count--;
        if(tray_count == 0 && timerGetContent == null)
        {
            timerGetContent = setInterval(getRecentContent,4000);
            alert("inside negitive");
        }
    }
    else if(status == "positive")
    {
        tray_count++;
        clearInterval(timerGetContent);
        timerGetContent = null;
        alert("inside positive")
    }

}

因此,当用户按下按钮以弹出托盘时,它会调用setTimer并在其执行任何其他操作之前将其传递给肯定,然后当他们按下按钮关闭托盘时,它会调用setTimer并将其传递给否定。我知道调用工作并且它被传递了正确的参数,我甚至知道它进入函数的正确部分取决于按下什么但有时候间隔没有被清除并且无论什么时候它都会继续发射我做。已经工作了几个小时,我完全被难过了。

编辑: 我试图将函数外的var timerGetContent作为全局变量。这有同样的行为问题。

EDIT2: 调用setTimers函数的函数:

function slide_out(event)
{
    clicked_element = document.getElementById(event.srcElement.id);
    var re_clicked = new RegExp(clicked_element.className, "g");
    if(clicked_element.className == "options-bar slide-out")
    {
        BACKGROUND.setTimers("positive");
        clicked_element.className = clicked_element.className.replace(re_clicked, '');
        clicked_element.className += "options-bar slide-out open";
    }
    else
    {
        clicked_element.className = clicked_element.className.replace(re_clicked, '');
        clicked_element.className += "options-bar slide-out";
        BACKGROUND.setTimers("negitive");
    }

另一件事,setTimers函数位于扩展的后台文件中,而此函数位于弹出窗口中。

3 个答案:

答案 0 :(得分:2)

尝试将var timerGetContent = null;移到函数外部,以便在调用setTimers之间保持不变:现在它是函数的本地函数。

答案 1 :(得分:1)

这里的主要问题是范围界定,正如Femi之前所说的那样。您必须var timerGetContent = null;移到函数声明之外。在第一个条件status == "login"中,您也遇到了逻辑错误。您将timerGetContent intervalID设置为null而不先清除它。

因此,如果您在调用setTimers("login");后调用setTimers("negitive");而未调用setTimers("positive");来首先清除时间间隔,那么您将始终至少有一个时间间隔。

我用console.log语句替换了你的函数调用以进行测试:

var tray_count = 0;
var timerGetContent = null;
function setTimers(status) {
    if(status == "login") {
        tray_count = 0;
        // Setting the intervalID to null will NOT clear the interval
        // If we do not clear the interval, calling setTimers('login')
        // will create a new interval and make previous interval
        // "unclearable" every time it is called
        clearInterval(timerGetContent);
        timerGetContent = null;
        timerGetContent = setInterval(function() {
            console.log('login intervalling')
            },400);

    } else if(status == "negitive") {
        tray_count--;
        if(tray_count == 0 && timerGetContent == null) {
            timerGetContent = setInterval(function() {
                console.log('negitive intervalling')
            },400);
            alert("inside negitive");
        }
    } else if(status == "positive") {
        tray_count++;
        clearInterval(timerGetContent);
        // calling clearInterval does not actually unset the intervalID variable
        // so we need to set it to null manually
        timerGetContent = null;
        timerGetBlasts = null;
    }

}

更新2014-07-14:修正了格式错字--cbarrick

答案 2 :(得分:0)

我建议你有一个定时器id的全局数组/对象,这样无论何时你创建一个新的计时器,你都可以将它推入,反之亦然。

我的看法:

timers = {};

function slide_out(event) {
  clicked_element = document.getElementById(event.srcElement.id);

  var re_clicked = new RegExp(clicked_element.className, "g");
  if (clicked_element.className == "options-bar slide-out") {
    BACKGROUND.setTimers("positive", clicked_element.id);
    clicked_element.className = clicked_element.className.replace(re_clicked, '');
    clicked_element.className += "options-bar slide-out open";

  } else {
      clicked_element.className = clicked_element.className.replace(re_clicked, '');
      clicked_element.className += "options-bar slide-out";
      BACKGROUND.setTimers("negitive", clicked_element.id);
  }

function setTimers(status, elementId) {
  var timerGetContent = null;
  if (status == "login") {
    tray_count = 0;
    timerGetContent = null;
    timerGetContent = setInterval(getContent, 4000);
    timers[elementId] = timerGetContent;
    alert("inside login");
  } else if (status == "negitive") {
      tray_count--;
      if (tray_count == 0 && timers[elementId] == undefined) {
        timerGetContent = setInterval(getRecentContent, 4000);
        timers[elementId] = timerGetContent;
        alert("inside negitive");
      }
  } else if (status == "positive") {
      tray_count++;
      clearInterval(timers[elementId]);
      delete timers[elementId];
      timerGetContent = null;
      alert("inside positive")
  }
}

如果我搞砸缩进,我很抱歉

干杯