dmitriymar,
Я если честно не понимаю, чего вы не поняли и почему утверждаете про синхронность исходя из однопоточности JavaScript, учитывая сколько в этом обсуждении уже написано про это.
Представьте мой пример в таком виде, есть объект и сложное UI, модель которого связана через события с нулевым таймаутом при emit. От пользователя приходят два события, которые имеют сложную обработку, допустим это будет mouseover и mousedown. Допустим, что они произошли практически одновременно. В синхронном коде обработчик mouseover будет выполняться до конца, после этого будет вызван обработчик mousedown. При организации кода через события с асинхронным выполнением произойдет mouseover, будет получен из кода emit, потом обработан mousedown, будет получен emit, потом обработчики, если они будут генерировать новые события и передавать управление с нулевым таймаутом, будут выполняться не последовательно, а в режиме вытесняющей очереди со случайным выбором. Дальнейшие разъяснения нужны?
Для подтверждения моих слов вот вам код. Если бы было все синхронно и просто очередью, до обработчики бы были вызваны в порядке, что алерты были бы такие: 1, 2, 4, 6, 3, 5, 7. Но они будут вызваны в таком порядке: 1, 2, 3, 4, 5, 6, 7. Потому что вызов события не мешает выполнению как-бы другого рута событий.
Поправьте, если я ошибаюсь и это тоже "синхронная" работа:
// Скрипт для работы событий:
var Ev = {
"__listeners__": {},
"EventEmitter": function(object) {
object.__listeners__ = {};
object.addEventListener = object.on = this.addEventListener;
object.removeEventListener = this.removeEventListener;
object.getEventListeners = this.getEventListeners;
object.clearEventListeners = this.clearEventListeners;
object.emit = this.emit;
},
"addEventListener": function(eventName, listener) {
eventName in this.__listeners__ ?
this.__listeners__[eventName].push(listener) :
this.__listeners__[eventName] = [listener];
return listener;
},
"removeEventListener": function(eventName, listener) {
if (eventName in this.__listeners__) {
for (var i in this.__listeners__[eventName])
if (this.__listeners__[eventName].hasOwnProperty(i))
if (this.__listeners__[eventName][i] === listener)
this.__listeners__[eventName].splice(i, 1);
}
},
"getEventListeners": function(eventName) {
if (eventName in this.__listeners__)
return this.__listeners__[eventName];
return null;
},
"emit": function(eventName, eventData) {
var self = this;
eventData = eventData || null;
if (eventName in this.__listeners__) {
for (var i in this.__listeners__[eventName])
if (this.__listeners__[eventName].hasOwnProperty(i)) {
setTimeout((function(i) { return function() { self.__listeners__[eventName][i](eventData); } })(i), 0);
}
}
}
};
// Какой-то конструктор:
var B = function() {
var self = this;
// Добавляем методы событий в наш объект:
Ev.EventEmitter(this);
// Подписываемся тремя обработчиками на событие "someEvent":
this.addEventListener("someEvent", function() {
self.emit("someEvent2");
alert(2);
});
this.addEventListener("someEvent", function() {
self.emit("someEvent3");
alert(3);
});
this.addEventListener("someEvent2", function() {
self.emit("someEvent4");
alert(4);
});
this.addEventListener("someEvent3", function() {
self.emit("someEvent5");
alert(5);
});
this.addEventListener("someEvent4", function() {
alert(6);
});
this.addEventListener("someEvent5", function() {
alert(7);
});
};
// Этот метод генерирует событие "someEvent":
B.prototype.generateEvent = function() {
alert("Let's start!");
// Генерируем событие:
this.emit("someEvent");
// Проверяем, остались ли мы в этом участке кода:
alert(1);
// Только теперь должно быть выполнение асинхронных обработчиков.
return false;
};
// Создаем объект и выполняем метод, генерирующий событие:
b = new B();
b.generateEvent();