Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Асинхронность в JavaScript (https://javascript.ru/forum/events/21311-asinkhronnost-v-javascript.html)

Андрей Параничев 04.09.2011 15:49

Асинхронность не в том, как работает "кассир" (однопоточность или многопоточность), а как устроена сама очередь и как из неё вызываются люди.

dmitriymar 04.09.2011 15:53

Цитата:

Сообщение от Андрей Параничев
а как устроена сама очередь и как из неё вызываются люди.

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

Gozar 04.09.2011 16:58

Асинхронное формирование потока выполнения. Не стек. Все согласны?

Хотя я даже не понимаю о чем вы спорите, любой человек видит разницу между тем же асинхронным и синхронным ajax, да и при работе с DOM тоже всё кристально ясно. Больше похоже на флуд или крючкотворство.

Андрей Параничев 04.09.2011 17:43

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();

monolithed 04.09.2011 17:58

dmitriymar, если асинхронность - характеристика процессов, не совпадающих по времени, то:

<p id="foo">0</p>

<script>
var src = "http://fc06.deviantart.net/fs41/i/2009/051/9/3/CIA_LOGO_by_krumbi.jpg?" + Math.random();
document.write('<img src="' + src + '" height="300" width="300" />');

function init(element) {  
    if(document.getElementById(element) !== null) {
        foo();
    }
    else {
        setTimeout(function() {
            init(element);
        }, 0);
    }
}

function foo() {
    var i = 0;
    return function() {
        if (i++ < 25) {
            document.getElementById('foo').innerHTML = Math.random();
        }
        else i = 0;
        setTimeout(arguments.callee, 100);
    }();
}

init('foo');
</script>


можно ли этот пример назвать асинхронным?

dmitriymar 04.09.2011 17:59

Цитата:

Сообщение от Андрей Параничев
В синхронном коде обработчик mouseover будет выполняться до конца, после этого будет вызван обработчик mousedown.

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

dmitriymar 04.09.2011 18:06

monolithed,
Ну здесь мешанка нтмл и скрипт. здесь изначально два потока-поток загрузки нтмл и поток скрипта. асинхронность также можно привести в пример при загрузке скриптов из разных субдоменов-типа грузятся параллельно и выполнится тот какой первым загрузится не дожидаясь загрузки того какой первым указан ,при условии что первым загрузился второй. Но и это не будет асинхронным выполнением скрипта-поскольку пользуется многопоточность браузера. и последний когда загрузится он дождётся когда отработает первый загрузившийся и только тогда начнёт работу-произойдёт "синхронизация" в итоге

Андрей Параничев 04.09.2011 18:14

dmitriymar,
Вы говорите глупости, если честно.

Очередь не синхронная. Попробуйте сами поставить 100 нулевых таймаутов и в это время словить событие клика на странице. Оно будет поймано и выполнится, вытесняя эти таймауты.

Попробуйте ловить все события мыши, события mousedown, mouseup, click если вы будете часто нажимать на кнопку могут смешаться, и может получится очередь выполнения обработчиков mousedown, mousedown, mouseup, mouseup, click, click.

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

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

Жалко только то, что сама по себе асинхронность, как и функции setTimeout/setInterval не являются частями какого-либо связанного с JavaScript стандарта. Так получается, что справедливо иметь несколько точек зрения на такой, казалось бы, очевидный вопрос.

dmitriymar 04.09.2011 18:33

Цитата:

Сообщение от Андрей Параничев
Очередь не синхронная. Попробуйте сами поставить 100 нулевых таймаутов и в это время словить событие клика на странице. Оно будет поймано и выполнится, вытесняя эти таймауты.

Сейчас уже перейду на маты.:-/
1 очередь выполняется последовательно
2 новые события могут ставиться не в конец очереди.-зависит и от браузеров и от событий какие уже в ней,задержки в тех же таймаутах.
3 при этом очередь с поставленными в неё событиями будет выполнятся от начала до конца последовательно
4 очередь по размеру ограниченна.
5 . 0 в таймауте может трактоваться как выполнить сразу так и выполнить минимальной задержкой в некоторых браузерах до 30 м.с. -зависит от браузера. Итого ситуация стоит 10 таймаутов с задержкой в 30 м.с. и если произойдёт событие то оно может стать как до них,так после них,так и между ними. Не стоит то,что рендомно возводить в систему,и рассматривать очередь как стек и на основе этого строить теории

Формирование очереди асинхронно с исполняемым кодом,но вот выполнение очереди всегда будет последовательно. действия будут выполняться в зависимости от того как они расположены в очереди. И причём здесь синхронность/асиинхронность-если изначально сказал что пример не корректен и работает согласно последовательности очереди и взаимодействия с очередью и не может быть примером асинхронности

Gozar 04.09.2011 18:42

http://javascript.ru/unsorted/async


Часовой пояс GMT +3, время: 13:16.