ClearInterval не работает (но только иногда) для вызова sever api - PullRequest
0 голосов
/ 10 августа 2011

У меня есть эта функция, которая должна каждые 4 секунды запрашивать у базы данных любое новое содержимое, которое могло быть опубликовано. Затем я беру возврат и обновляю ленту с помощью динамического HTML, созданного из того, что вернулось с сервера. Все это прекрасно работает.

Моя проблема в том, что в составе 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 и передает его отрицательно , Я знаю, что вызовы работают и что ему передаются правильные параметры, я даже знаю, что он входит в правую часть функции в зависимости от того, что нажимается, но бывают моменты, когда интервал просто не очищается, и он продолжает срабатывать, несмотря ни на что Я делаю. Я работал над этим часами, и я в полном замешательстве.

Edit: Я пытался иметь переменную 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 ]

2 голосов
/ 10 августа 2011

Попробуйте переместить var timerGetContent = null; за пределы функции, чтобы она сохранялась между вызовами setTimers: сейчас она является локальной для функции.

1 голос
/ 10 августа 2011

Основной проблемой здесь было определение объема, как и предполагал Феми. Вы должны переместить 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

0 голосов
/ 15 августа 2011

Я бы посоветовал вам иметь глобальный массив / объект идентификаторов таймера, чтобы при каждом создании нового таймера вы добавляли его и наоборот.

Мой дубль:

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")
  }
}

Прошу прощения, если я испортил отступ

Приветствия

...