Не выполняйте функцию, пока не завершится внутренняя анимация - PullRequest
2 голосов
/ 20 января 2011

Краткая версия

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

Например, когда вызывается нижеприведенная функция, я не хочу, чтобы ее снова вызывали до завершения процедуры внутреннего таймера:

function doSomething() {
   ... blah blah blah ...

   someElement.fadeOut(999, function() {
       // Don't let doSomething get invoked until the fadeOut animation has finished
   });
}

Длинный вопрос

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

Функция для циклического воспроизведения верхнего элемента новостей выглядит так:

function advanceTicker(id) {
    // Get the first item
    var firstItem = $(id + ' li:first');
    var firstItemMarkup = firstItem.html();

    // Fade out the first item then move it to the bottom
    firstItem.fadeOut(999, function() {
        $(this).remove();  // Remove the first item

        // Tack the first item to the end of the list
        $(id).append('<li style="display:none">' + firstItemMarkup + '</li>');

        // Make the new first item visible
        $(id + ' li:first').show();
    });
}

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

Я понимаю, почему (или, по крайней мере, я так думаю) - вызов fadeOut, который был выполнен при первом нажатии кнопки, не завершился к тому времени, когдакнопка нажимается снова, поэтому тот же firstItem выбирается при втором нажатии кнопки и добавляется снова.

Я предполагаю, что мне нужно убедиться, что эта функция advanceTicker не вызывается во время "в процессе"«.Есть ли элегантный способ сделать это?То, что у меня сейчас есть - что-то вроде взлома - это переменная флага, например:

var inAnimation = false;
function advanceTicker(id) {
    if (!inAnimation) {
        inAnimation = true;

        ...

        firstItem.fadeOut(999, function() {
             ...

             inAnimation = false;
        });
    }
}

Приведенный выше подход кажется неправильным и пахнет как проблема состояния гонки.

1 Ответ

3 голосов
/ 20 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...