04.09.2011, 13:53
|
|
|
Регистрация: 21.02.2008
Сообщений: 1,250
|
|
Вот, в качестве примера, реализация асинхронного кода на основе собственных событий и использования функции 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();
Последний раз редактировалось Андрей Параничев, 04.09.2011 в 13:55.
|
|
04.09.2011, 14:32
|
х.з
|
|
Регистрация: 21.11.2010
Сообщений: 4,588
|
|
Сообщение от Андрей Параничев
|
Вот, в качестве примера, реализация асинхронного кода на основе собственных событий и использования функции setTimeout:
|
Я конечно извиняюсь ,но в чём здесь ассинхронность? события не запустятся пока скрипт не доработает. поскольку события идут через очередь,а правила когда очередь начнёт срабатывать чёткие
Сообщение от Андрей Параничев
|
// Если первым будет выведено alert(1), значит мы работаем асинхронно, поскольку вызов
// метода emit произошел, но код обработчика не выполнился последовательно. Затормозим
// выполнение на 3 секунды для точной проверки:
|
С чего это такие заключения?
Последний раз редактировалось dmitriymar, 04.09.2011 в 14:39.
|
|
04.09.2011, 14:50
|
|
|
Регистрация: 21.02.2008
Сообщений: 1,250
|
|
dmitriymar,
В общем виде асинхронность не значит одновременное выполнение кода. Это всего лишь не последовательное выполнение кода, основанное (чаще всего) на событиях.
Просто тот же самый msdn может запутать программиста, поскольку для увеличения скорости работы асинхронных методов, в .NET реализация обработчиков асинхронных вызовов и событий сделана в отдельном потоке и асинхронность просто скрывает части реализации многопоточности для программиста, но как уже было сказано, это не обязательное условие.
Цитата:
|
чего здесь асинхронного? или в чём поведение асснхронное? асинхронное было бы если бы они до паузы запустились.
|
Поведение этого кода не последовательно, а значит асинхронно. Мы генерировали событие и продолжили выполнять код метода, когда обработчики будут вызваны в "свободное время", отложено от момента вызова emit.
Просто из-за "обычных" примеров асинхронности в JavaScript происходит путаница. Асинхронность событий DOM не в том, что пользователь может стать источником события в любое время, а то, что в потоке JavaScript выполнение кода может быть прервано при выходе из текущего scope и выполнится обработчик этого события. Соответственно и для XHR - асинхронность не в том, что мы сделали вызов и он выполняется в то время, когда мы выполняем другой код, а в том, что при наступлении события (смена статуса, получение данных) будут вызваны соответствующие обработчики, даже если они будут выполнены в основном потоке выполнения.
Последний раз редактировалось Андрей Параничев, 04.09.2011 в 14:52.
|
|
04.09.2011, 15:01
|
х.з
|
|
Регистрация: 21.11.2010
Сообщений: 4,588
|
|
Сообщение от Андрей Параничев
|
Поведение этого кода не последовательно, а значит асинхронно. Мы генерировали событие и продолжили выполнять код метода, когда обработчики будут вызваны в "свободное время", отложено от момента вызова emit.
|
Нет исполнение кода как раз последовательно ничем не отличается от кода devote, только более усложнённое . события генерятся и становятся в очередь ,какая будет выполнена после завершения выполняемого кода.И исполнение кода последовательно в принципе-сначала отрабатывает код потом отработает очередь.Нет в этом примере асинхронности-есть стандартное поведение очереди.Да и события отрабатываются последовательно-в той последовательности в какой они стоят в очереди
Последний раз редактировалось dmitriymar, 04.09.2011 в 15:11.
|
|
04.09.2011, 15:18
|
|
|
Регистрация: 21.02.2008
Сообщений: 1,250
|
|
dmitriymar,
Цитата:
|
принципе-сначала отрабатывает код потом работает очередь
|
Ну если этот пример конкретный рассматривать, то возможно вы и правы, но представьте себе, что первым событием будет applicationReady, внутри обработчика этого события будут генерироваться новые события, которые будут зависеть от каких-то данных, будут вызваны новые события и это уже не будет банальным примером очереди (хотя по сути событийная модель и является очередью в первую очередь, простите за тавтологию).
Да и даже в этом примере не гарантируется последовательная очередь выполнения обработчиков, они могут быть выполнены в произвольном порядке.
Те же события DOM обрабатываются идентично тому, как обрабатывается событие в примере, на самом деле.
Именно в том, что обработчик будет вызван "между" вызовами других обработчиков и заключается асинхронность.
Если в клиентском коде это не так очевидно, то в Node.js, где главный источник множества событий это web-сервер, это просматривается куда лучше. Поскольку после вызова emit из моего примера может быть обработан другой клиент, например.
Последний раз редактировалось Андрей Параничев, 04.09.2011 в 15:23.
|
|
04.09.2011, 15:23
|
х.з
|
|
Регистрация: 21.11.2010
Сообщений: 4,588
|
|
Сообщение от Андрей Параничев
|
Да и даже в этом примере не гарантируется последовательная очередь выполнения обработчиков, они могут быть выполнены в произвольном порядке.
|
порядок не произвольный-у очереди есть свои правила относительно порядка событий в ней
Сообщение от Андрей Параничев
|
Именно в том, что обработчик будет вызван "между" вызовами других обработчиков и заключается асинхронность.
|
в чём? он будет вызван когда подойдёт его очередь-это синхронность
пример из жизни -очередь на оплату допустим комунальных
люди из очереди платят синхронно или асинхронно-кто когда захочет или могут оплатить когда кассир отсутствует?(выпоняется другие действия кассиром аналогия с выполнением кода вызвавшим событие)
а вот добавление и убывание людей из очереди-асинхронно- никто не дожидается события какогото чтоб стать в очередь да и чтоб выйти из неё не обязательно выполнить оплатить комуналку-но такого нет в языке- соответственно выполнение очереди в языке синхронно
Кассир -это js -он синхронен или асинхронен? Я думаю что всё таки синхронен. когда нет других задач обслуживает очередь. когда и очереди нет ничего не делает если нет других задач. а асинхронный аякс-можно сравнить с помощником кассира ,какой принёс платёж и положил его на стол ,а кассир его обработает когда до него очередь дойдёт.
P.S. может мне написать книгу раскраску JS для малышей.для детей от 7 до 9 лет?)))
Последний раз редактировалось dmitriymar, 04.09.2011 в 15:41.
|
|
04.09.2011, 15:31
|
|
|
Регистрация: 21.02.2008
Сообщений: 1,250
|
|
dmitriymar,
Если между вызовами могут быть обработаны другие события, какая же это синхронность? Была бы синхронность, если бы был прямой вызов, а не обернутый в таймаут.
И в этом примере порядок может быть произвольным. Например у меня алерты выскакивают 1, 2, 3, 4; 1, 3, 2, 4; и так далее.
|
|
04.09.2011, 15:36
|
|
|
Регистрация: 21.02.2008
Сообщений: 1,250
|
|
dmitriymar,
То, что вы описываете, это многопоточность.
Если рассматривать асинхронность на примере очереди, то лучше уж так:
Люди пришли в офис и получили номерки от 1 до N. Работает одно окно (но где-то может работать два окна), из которого людей вызывают по номеру. При этом в зависит все не только от готовности документов в окне, но и от самих людей в очереди, например, вызвали 3его номера, работают с ним, тут подошли в документы для 14, вызвали его, когда закончили с ним по результатам стали готовы документы для 4ого, вызвали 4ого, после которого стали готовы документы для 8ого и вызвали его, потом документов нет какое-то время, потом пришел документ 5ого, работали с ним, и так далее и тому подобное.
Последний раз редактировалось Андрей Параничев, 04.09.2011 в 15:43.
|
|
04.09.2011, 15:44
|
х.з
|
|
Регистрация: 21.11.2010
Сообщений: 4,588
|
|
Сообщение от Андрей Параничев
|
То, что вы описываете, это многопоточность.
|
Еще раз перечитай без шаблонов. многопоточность- да.но мы говорим за синхронность и асинхронность. работает ли кассир синхронно или асинхронно?
|
|
04.09.2011, 15:45
|
х.з
|
|
Регистрация: 21.11.2010
Сообщений: 4,588
|
|
Сообщение от Андрей Параничев
|
а не обернутый в таймаут.
|
таймаут ставит в очередь и положение в очереди будет в зависимости от таймаута -а очередь отрабатывает последовательно-синхронно.и чего здесь асинхронного если кассир сначала отрабатывает события другие(открыть тоже окошко) а затем очередь. было бы странно(асинхронно) если бы он платежи принимал при закрытом окошке.
Пример конечно спорен но всёже.
Последний раз редактировалось dmitriymar, 04.09.2011 в 15:49.
|
|
|
|