Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 12.08.2013, 13:15
Кандидат Javascript-наук
Отправить личное сообщение для FanAizu Посмотреть профиль Найти все сообщения от FanAizu
 
Регистрация: 08.03.2011
Сообщений: 148

Очередь выполнения
На сколько я знаю, js это однопоточный язык. То есть, в любой момент времени выполняться может только одна порция кода. Если же срабатывает какое-то асинхронное событие, например, клик мышью, таймер, завершение аякс запроса, то обработчики этих событий становятся в очередь и ждут завершения текущего выполняемого блока кода. Пока же текующий выполняемый блок кода не завершен, обработчики просто стоят в очереди и ждут.

Прочел все это в статьях различных.

Вот мой код:
function test()
{
	console.log(1);
	alert(1);
	console.log(2);
	$.ajax
	(
		{
			type: "POST",
			dataType: "json",
			contentType: "application/json",
			url: apiRoute + "auth",
			data: model,
			complete: function (data) 
			{console.log(3);alert(2);console.log(4);
				parcelDataJtLog.authenticationStatusCode = data.status;
				parcel.parcel('endFakeValidation');
			},
			headers:
			{
				'RequestVerificationToken': token
			},
			xhrFields: 
			{
				withCredentials: true
			}
		}
	);
	console.log(5);
	alert(3);
	console.log(6);
	alert(4);
	console.log(7);
	return true;
}

test();


Исходя из описанного в начале поста, в консоль должно быть выведено:

1, 2, 5, 6, 7, 3, 4.
То есть: вывело в консоль 1, открылся алерт с цифрой 1, закрыл алерт, вывело в консоль 2, вывело в консоль 5, открылся алерт с цифрой 3, вывело в консоль 6, открылся алерт с цифрой 4, закрыли алерт, вывело в консоль 7, из очереди выполнения выполняется обработчик события завершения аякса, вывело в консоль 3, открылся алерт с цифрой 2, закрыли алерт, вывело в консоль 4.

Но на практике имею:
1, 2, 5, 3, 4, 6, 7

Что не так в моем понимание работы js?
Ответить с цитированием
  #2 (permalink)  
Старый 12.08.2013, 13:40
Аватар для ОлегА
Профессор
Отправить личное сообщение для ОлегА Посмотреть профиль Найти все сообщения от ОлегА
 
Регистрация: 25.08.2011
Сообщений: 420

скорее всего это произошло потому что пока вы нажимали на алерт 3 (ок), у вас успел выполнится аякс запрос и вывел вам 3,4 а потом уже 6,7, попробуйте алерты убрать, то скорее всего у вас получится именно то что вы ожидали
Ответить с цитированием
  #3 (permalink)  
Старый 12.08.2013, 13:45
Кандидат Javascript-наук
Отправить личное сообщение для FanAizu Посмотреть профиль Найти все сообщения от FanAizu
 
Регистрация: 08.03.2011
Сообщений: 148

Сообщение от ОлегА Посмотреть сообщение
скорее всего это произошло потому что пока вы нажимали на алерт 3 (ок), у вас успел выполнится аякс запрос и вывел вам 3,4 а потом уже 6,7, попробуйте алерты убрать, то скорее всего у вас получится именно то что вы ожидали
Так а почему обработчик завершения аякс запроса отрабатывает раньше, чем закончится текущий блок js кода? Разве обработчик завершения аякс кода не должен стать в очередь и ждать завершения текущего блока кода?
Ответить с цитированием
  #4 (permalink)  
Старый 12.08.2013, 13:49
Аватар для ОлегА
Профессор
Отправить личное сообщение для ОлегА Посмотреть профиль Найти все сообщения от ОлегА
 
Регистрация: 25.08.2011
Сообщений: 420

FanAizu,
какого блока? код аякс запроса у вас раньше находится чем алерт 3, поэтому он и раньше выводит, а когда вызывается алерт происходит как бы пауза в js и то что находится после алерта не выполнится пока ты не нажмешь ок
Ответить с цитированием
  #5 (permalink)  
Старый 12.08.2013, 14:44
Аспирант
Отправить личное сообщение для NeoN Посмотреть профиль Найти все сообщения от NeoN
 
Регистрация: 01.03.2013
Сообщений: 77

Думаю этот скрипт у вас работает так:
сначала в консоли записывается 1 и 2. потом отправляеся запрос и ожидается ответ на него. Но поскольку аякс запрос работает в асинхронном режиме, на этом программа не пересает выполняться далее, поэтому в консоли после этого записывается 5. и выводится окошко с алертом 3. когда алерт выводится, в это время приходит ответ на посланный ранее запрос и выполняется эта часть кода:
complete: function (data)
{console.log(3);alert(2);console.log(4);
parcelDataJtLog.authenticationStatusCode = data.status;
parcel.parcel('endFakeValidation');
}
потому в консоли прописываеся 3 и 4.
а затем программа продолжает дальнейшее выполнение и в косноли мы видим 6 и 7

Последний раз редактировалось NeoN, 12.08.2013 в 14:48.
Ответить с цитированием
  #6 (permalink)  
Старый 12.08.2013, 15:21
Аспирант
Отправить личное сообщение для NeoN Посмотреть профиль Найти все сообщения от NeoN
 
Регистрация: 01.03.2013
Сообщений: 77

Сообщение от Дзен-трансгуманист Посмотреть сообщение


Кто-нибудь может объяснить настолько непредсказуемое поведение?

Мне вот тоже стало интересно, почему асинхронный код прерывает синхронный не дожидаясь опустошения стека вызовов.
сколько я не пробовал в опере запустить твой код, в консоли одна и та же последовательность была. а именно эта:
a1, a2, b1, b2, c1, с2, d1
как и должно быть
Ответить с цитированием
  #7 (permalink)  
Старый 12.08.2013, 15:27
Кандидат Javascript-наук
Отправить личное сообщение для FanAizu Посмотреть профиль Найти все сообщения от FanAizu
 
Регистрация: 08.03.2011
Сообщений: 148

Сообщение от NeoN Посмотреть сообщение
сколько я не пробовал в опере запустить твой код, в консоли одна и та же последовательность была. а именно эта:
a1, a2, b1, b2, c1, с2, d1
как и должно быть
В мозиле совсем другая последовательность у меня получилась.
Ответить с цитированием
  #8 (permalink)  
Старый 12.08.2013, 16:04
Аспирант
Отправить личное сообщение для NeoN Посмотреть профиль Найти все сообщения от NeoN
 
Регистрация: 01.03.2013
Сообщений: 77

нашел в комментах на этом сайте:

Цитата:
Автор: Dmitry A. Soshnikov, дата: 19 ноября, 2009 - 14:45
#permalink

В Firefox, в setTimeout первым аргументом передаётся "просроченное время", "задержка" (если таковые возникнут) в ходе интерпретации кода. Т.е., если setTimeout не успевает запуститься после назначенного времени (например, через 100мс), эта "просроченная задержка" фиксируется первым параметром.

Далее, когда поток освободился и готов принять (вклинить) код setTimeout-a, проверяется, есть ли "просроченное время", и если есть, то код может выполнится моментально (проверить можно, если поставить alert сразу после вызова setTimeout-a и подождать некоторое время, превышающее интервал таймаута).

Простой пример:
setTimeout(function () {
alert(arguments[0]); // ah?
}, 0);

Или даже так (чтобы приблизать к Вашему случаю):
setTimeout(function (myParam) {
alert(myParam); // wth?
}, 0);

Почитать можно в багтреккере:

https://bugzilla.mozilla.org/show_bug.cgi?id=10637
https://bugzilla.mozilla.org/show_bug.cgi?id=263945
ссылка: http://javascript.ru/blog/subzey/Firefox-setTimeout
Ответить с цитированием
  #9 (permalink)  
Старый 12.08.2013, 17:21
Аспирант
Отправить личное сообщение для NeoN Посмотреть профиль Найти все сообщения от NeoN
 
Регистрация: 01.03.2013
Сообщений: 77

наверное, фф работает каждый раз работает по-разному в зависимости от того, через какие промежутки времени нажимается ок на алертах

поставь интервал в 1 секунду и код в фф заработает как надо, если нажимать ок достаточно быстро)

Последний раз редактировалось NeoN, 12.08.2013 в 17:24.
Ответить с цитированием
  #10 (permalink)  
Старый 12.08.2013, 18:02
Кандидат Javascript-наук
Отправить личное сообщение для FanAizu Посмотреть профиль Найти все сообщения от FanAizu
 
Регистрация: 08.03.2011
Сообщений: 148

Сообщение от Дзен-трансгуманист Посмотреть сообщение
Ну да, я не уточнил, что пробовал в ФФ. Значит к опере претензий нет.

Но вопрос не отвечен:
Почему мозилла работает каждый раз по-разному?


ps: гуглодудл в тему

Причём ситуация не только с timeout-ом. В моем случае это ajax запросы. почему асинхронный код прерывает синхронный не дожидаясь опустошения стека вызовов.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с jasmine подсчет времени выполнения теста voice Библиотеки/Тулкиты/Фреймворки 2 26.03.2013 17:47
Очередь XML запросов Евгений М AJAX и COMET 4 01.02.2012 11:05
Время выполнения z700i Общие вопросы Javascript 7 02.11.2011 16:10
Скорость выполнения кода mycoding Общие вопросы Javascript 6 23.04.2010 13:28
разное время выполнения операции ropowek Events/DOM/Window 2 08.10.2008 13:27