Могут ли обработчики событий JS прервать выполнение другого обработчика? - PullRequest
3 голосов
/ 05 ноября 2011

У меня следующая проблема. Я создал класс, в конструктор которого я загружаю пару изображений, и мне нужно отложить оставшиеся инициализации до полной загрузки. Код, который я использовал, выглядит следующим образом (выдержка из конструктора):

var self = this;
var imagesToLoad = 4;

var finishInit = function() {
    alert(imagesToLoad);
    imagesToLoad--;
    if (imagesToLoad == 0) {
       // remaining initializations
    }
}

this._prevIcon = new Image();
this._prevIcon.onload = finishInit; 
this._prevIcon.src = "img1.png";
this._nextIcon = new Image();
this._nextIcon.onload = finishInit; 
this._nextIcon.src = "img2.png";
this._pauseIcon = new Image();
this._pauseIcon.onload = finishInit; 
this._pauseIcon.src = "img3.png";
this._playIcon = new Image();
this._playIcon.onload = finishInit; 
this._playIcon.src = "img4.png";

К моему удивлению, при запуске отображаемые диалоги читают 4,4,4,4 в Firefox 7 и 4,3,2,4 в IE 9. Я запутался, потому что полагал, что JS однопоточный и поэтому один обработчик событий не должен прерывать другой. Где подвох (или моя ошибка)?

Спасибо заранее. С наилучшими пожеланиями, Томек

1 Ответ

6 голосов
/ 05 ноября 2011

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

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

См. в этом посте для дальнейшего обсуждения очереди событий Javascript.

Изображения загружаются в фоновом режиме с использованием собственной сети ОС.Несколько изображений могут быть загружены одновременно.Обработчики .onload() будут запускать только по одному за раз, но поскольку изображения загружаются одновременно, нет никакой гарантии порядка загрузки в коде, как у вас.Кроме того, оповещения могут влиять на время, потому что они блокируют выполнение javascript, но не блокируют выполнение загрузки изображения.

Я не понимаю ни 4,4,4,4, ни 4,3,2,4 последовательности.Они оба должны показать 4,3,2,1.Вы должны показать нам полностью рабочую версию кода, чтобы узнать, что является причиной этого.Я предполагаю, что у вас либо есть проблемы с областями видимости ваших переменных, которые отслеживают количество происходящего в вашем коде, чем вы раскрыли в своем вопросе.

Вы можете увидеть рабочую версию этоговид кода здесь: http://jsfiddle.net/jfriend00/Bq4g3/.

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