
12.08.2013, 13:15
|
Кандидат Javascript-наук
|
|
Регистрация: 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?
|
|

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

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

12.08.2013, 13:49
|
 |
Профессор
|
|
Регистрация: 25.08.2011
Сообщений: 420
|
|
FanAizu,
какого блока? код аякс запроса у вас раньше находится чем алерт 3, поэтому он и раньше выводит, а когда вызывается алерт происходит как бы пауза в js и то что находится после алерта не выполнится пока ты не нажмешь ок
|
|

12.08.2013, 14:44
|
Аспирант
|
|
Регистрация: 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.
|
|

12.08.2013, 15:21
|
Аспирант
|
|
Регистрация: 01.03.2013
Сообщений: 77
|
|
Сообщение от Дзен-трансгуманист
|
Кто-нибудь может объяснить настолько непредсказуемое поведение?
Мне вот тоже стало интересно, почему асинхронный код прерывает синхронный не дожидаясь опустошения стека вызовов.
|
сколько я не пробовал в опере запустить твой код, в консоли одна и та же последовательность была. а именно эта:
a1, a2, b1, b2, c1, с2, d1
как и должно быть
|
|

12.08.2013, 15:27
|
Кандидат Javascript-наук
|
|
Регистрация: 08.03.2011
Сообщений: 148
|
|
Сообщение от NeoN
|
сколько я не пробовал в опере запустить твой код, в консоли одна и та же последовательность была. а именно эта:
a1, a2, b1, b2, c1, с2, d1
как и должно быть
|
В мозиле совсем другая последовательность у меня получилась.
|
|

12.08.2013, 16:04
|
Аспирант
|
|
Регистрация: 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
|
|

12.08.2013, 17:21
|
Аспирант
|
|
Регистрация: 01.03.2013
Сообщений: 77
|
|
наверное, фф работает каждый раз работает по-разному в зависимости от того, через какие промежутки времени нажимается ок на алертах
поставь интервал в 1 секунду и код в фф заработает как надо, если нажимать ок достаточно быстро)
Последний раз редактировалось NeoN, 12.08.2013 в 17:24.
|
|

12.08.2013, 18:02
|
Кандидат Javascript-наук
|
|
Регистрация: 08.03.2011
Сообщений: 148
|
|
|
|
|
|