таймер JavaScript или интервалы создаются в цикле с помощью закрытия

Я использую jQuery для установки таймера или цикла интервала на нескольких элементах для проверки их каждая пара секунды. Я попытался установить таймер и проверить, должен ли я перезапустить его, или установка и интервал и проверка, если я должен остановить его.

Хотя упрощено, это в основном, в чем я нуждаюсь:

var mytimers = new Array();
$('div.items').each(function() {
    myID = $(this).attr('id');
    mytimers[myID] = setInterval( function() { myFunction(myID) } , 3000)
});
function myFunction(param) {
    alert(param);
    if (something()) {
        clearInterval(mytimers[param]);
    }
}

Идентификатор для объектов класса является id_1, id_2, id_3. Но я просто получаю 3 предупреждения все предоставление id_3. В моем коде я начался, пытаясь передать 'это', но продолжал упрощать его для выяснения проблемы.

Как я могу заставить это копировать переменную в новый адрес каждый раз? Я знаю, что должен использовать закрытия. Это, кажется, ссылается на другой var никакая мать что.

Я пытался упростить его до цикла с таймерами как так:

function tester(item) {
    return function() {
        alert(item);
    };
}
for(x=1;x<=3;x++) {
    setTimeout( '(function() { tester(x) })(x)' , 3000);
}

Но я думаю, что просто делаю свою проблему хуже, и это, кажется, ничего не делает.

Я искал предыдущие вопросы, но большинство заполнено тоннами дополнительного кода вместо того, чтобы сократить его конкретный вопрос и решено некоторым другим способом. Я хотел бы понять, как это работает лучше путем получения этой работы в качестве примера. Я действительно справлялся при записи этого, чтобы выяснить, что я могу выделить таймер с функцией помощи.

function tester(item)
    alert(item);
function myTimer(item)
    setInterval( function() { tester(item); }, 3000);
for(x=1;x<=3;x++)
    myTimer(item);

Как это может быть сделано без этого? Есть ли некоторый лучший путь?

9
задан phazei 20 July 2010 в 20:28
поделиться

3 ответа

Вы находитесь в закрытии, когда используете each, вы просто забыли var, чтобы сделать вашу переменную приватной в области видимости функции

var mytimers = new Array();
$('div.items').each(function() {
    **var** myID = $(this).attr('id'); 
    mytimers[myID] = setInterval( function() { myFunction(myID) } , 3000)
});
function myFunction(param) {
    alert(param);
    if (something()) {
        clearInterval(mytimers[param]);
    }
}
3
ответ дан 4 December 2019 в 22:27
поделиться

Иметь локальную переменную myID для анонимной функции,

var myID = $(this).attr('id');
4
ответ дан 4 December 2019 в 22:27
поделиться

Значит, вы хотите запускать myFunction для каждого из совпадающих элементов каждые три секунды?

Попробуйте следующее:

$('div.items').each( myFunction(this) );

var myFunction = function(elem) {
    return function() {
        if ( something(elem) ) {
            //return or do something with elem
        } else {
            window.setTimeout( myFunction(elem), 3000 );
        }
    }
};

Если условие в something ( ) выполнено, все готово, в противном случае функция планирует повторный запуск через 3 секунды с тем же элементом, что и раньше. Вы можете вызывать это столько раз, сколько хотите для разных элементов, каждый вызов имеет свой собственный elem .

Я предпочитаю передавать такие объекты, как элемент, и откладывать работу с их внутренностями до последнего момента. Пусть something () беспокоит идентификатор или что-то еще.

Никакой другой гимнастики с ассоциативным массивом (вместо new Array () вы можете просто использовать {} ), или clearInterval , или идентификаторы необходимы.

Чтобы на самом деле обратиться к вашему решению, как сказал Маримуту, вы оставили var в объявлении myID , что означает его глобальное значение, и оно перезаписывается на каждой итерации. В результате, когда setInterval вызывает myFunction вместо получения уникального локального myID через закрытие, вы получаете глобальный, который уже был перезаписан неограниченное количество раз.

1
ответ дан 4 December 2019 в 22:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: