Гарантируются ли обработчики событий до того, как будут вызваны обратные вызовы AJAX?

Предположим, что у меня есть обработчик событий, который вызывает два вызова AJAX на сервер:

$("#foo").click(function(){ 
    $.get("bar", function(){ alert("Hello"); });
    $.get("baz", function(){ alert("World"); });
});

Я понимаю, что порядок, в котором вызываются обратные вызовы, является недетерминированным, поскольку он зависит от того, сколько времени занимает каждый запрос и т.д.

Но вот мой вопрос: гарантировано ли, что я дойду до конца обработчика событий до вызова любой из функций обратного вызова? Я прочитал, что все Javascript для страницы выполняется в одном потоке, поэтому я думаю, что это означает, что мой обработчик событий click должен быть завершен до того, как любой из вызывающих вызовов может быть вызван.

Это правильно? Или возможно, что первый запрос может быть завершен И первый обратный вызов выполняется до того, как мы дойдем до конца нашего обработчика событий?

Ответ 1

Да, это гарантировано, и вы правы - есть только один поток (игнорируя web-worker на данный момент). Когда часть кода JavaScript выполняется (занимает поток выполнения) и появляется обратный вызов AJAX (или любое другое событие GUI, время ожидания и т.д.), Он ставится в очередь и ждет, пока поток выполнения не станет свободным (текущий фрагмент кода завершается).

JavaScript-движок никогда не будет прерывать запуск кода для обработки входящего события - события всегда будут осторожно ждать в очереди. Именно по этой причине графический интерфейс, кажется, замерзает при выполнении кода с интенсивным использованием ЦП - никакие события не обрабатываются. Вот почему синхронные запросы AJAX плохие.

См. также

Ответ 2

Да, JavaScript однопоточный, поэтому ваше исполнение никогда не будет выгружено.

Асинхронные обратные вызовы и события работают одинаково; ваш обработчик для mousedown гарантированно завершит работу перед вашим обработчиком для mouseup, даже если ваш обработчик mousedown занимает 2 секунды, и вы сразу же отпустите кнопку мыши.

То же самое касается обратного вызова AJAX, он попадает в ту же (вид) очередь, что и события, ожидающие обработки

Ответ 3

Интересным поводом для этого будет вместо $.get(), скажем, мы использовали promises, который мы получаем из другого места (т.е. фактический асинхронный вызов был сделан в другом месте) (-Почему у нас будет такая ситуация? Возможно, у нас есть функция memoized query.)

Теперь, если вы используете jQuery promises, обратные вызовы будут вызываться синхронно, если они уже разрешены. Это когда-нибудь проблема? Хорошо, зависит от вашего требования. Если это произойдет, вы можете обернуть код обратного вызова в setTimeout (cb, 0).

С другой стороны, что, если вы хотите, чтобы обратные вызовы были выгружены? См. мои примеры здесь

Ответ 4

Я понимаю, что порядок, в котором вызываются обратные вызовы, является недетерминированным, поскольку он зависит от того, сколько времени занимает каждый запрос и т.д.

В том виде, как вы написали это да... но есть способы организовать и контролировать это... а именно defffes и promises.

Вот хороший обзор: http://net.tutsplus.com/tutorials/javascript-ajax/wrangle-async-tasks-with-jquery-promises/

Правильное использование их гарантирует, что вы не столкнетесь с какой-либо проблемой, которую вы пытаетесь избежать.

** Как отметил @Juan, это не черный и белый ответ на заданный вами вопрос. Я просто пытаюсь указать вам разные направления или способы взглянуть на одну и ту же проблему, чтобы вы могли более четко определить ваше ожидаемое поведение.