Вот, в качестве примера, реализация асинхронного кода на основе собственных событий и использования функции setTimeout:
// Скрипт для работы событий:
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() {
// Добавляем методы событий в наш объект:
Ev.EventEmitter(this);
// Подписываемся тремя обработчиками на событие "someEvent":
this.addEventListener("someEvent", function() {
alert(2);
});
this.addEventListener("someEvent", function() {
alert(3);
});
this.addEventListener("someEvent", function() {
alert(4);
});
};
// Этот метод генерирует событие "someEvent":
B.prototype.generateEvent = function() {
alert("Let's start!");
// Генерируем событие:
this.emit("someEvent");
// Проверяем, остались ли мы в этом участке кода:
alert(1);
// Если первым будет выведено alert(1), значит мы работаем асинхронно, поскольку вызов
// метода emit произошел, но код обработчика не выполнился последовательно. Затормозим
// выполнение на 3 секунды для точной проверки:
var n = new Date();
while(new Date() - n < 3000) {};
// Только теперь должно быть выполнение асинхронных обработчиков.
};
// Создаем объект и выполняем метод, генерирующий событие:
b = new B();
b.generateEvent();