JQuery AJAX-запрос ведет себя синхронно по неизвестной причине - PullRequest
1 голос
/ 21 марта 2011

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

$(".widget").each(function() {
    // snip - url, def, and tempParams defined here
$.ajax({
    url: url, 
    dataType: "jsonp", 
    type: "POST",
    data: {params: tempParams},
    success: function(data) {
        var st = new Date().getTime();
        console.error("Start " + def.name + " @" + st);
        doSomething(data);
        var et = new Date().getTime();
        console.error("End " + def.name + " @" + et);
        console.error("Duration " + def.name + " " + (et-st) + " ms.");
    }
});

Вывод на консоль ясно показывает функции успеха, выполняющиеся по порядку, а неасинхронно:

Start f1 @1300738891705
End f1 @1300738891744
Duration f1 39 ms.
Start f2 @1300738892746
End f2 @1300738893280
Duration f2 534 ms.
Start f3 @1300738893282
End f3 @1300738893303
Duration f3 21 ms.
Start f4 @1300738893305
End f4 @1300738893306
Duration f4 1 ms.
Start f5 @1300738893484
End f5 @1300738895609
Duration f5 2125 ms.

Мысли?Я чувствую, что это должно быть что-то очевидное, что я пропускаю.

Ответы [ 4 ]

1 голос
/ 21 марта 2011

Все отладочные выходные данные получены из функции success, которая вызывается после завершения запроса и получения результата. Даже если запросы выполнялись асинхронно, результаты обрабатываются один за другим, когда они поступают.

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

Результаты запросов ajax могут поступать в том же порядке, в котором вы их запрашивали, так что вы получаете сообщения журнала по порядку. Но также возможно, что один запрос займет больше времени, и вы, например, получите вывод журнала за f4 перед выводом f3, потому что этот результат поступил раньше.

1 голос
/ 21 марта 2011

Попробуйте вместо этого ...

var st = new Date().getTime();
console.error("Start " + def.name + " @" + st);
$.ajax({
    url: url, 
    dataType: "jsonp", 
    type: "POST",
    data: {params: tempParams},
    success: function(data) {
        doSomething(data);
        var et = new Date().getTime();
        console.error("End " + def.name + " @" + et);
        console.error("Duration " + def.name + " " + (et-st) + " ms.");
    }
});
1 голос
/ 21 марта 2011

Я думаю, вы оба путаете эти два термина.Асинхронный с точки зрения AJAX и, следовательно, JQuery просто означает, что сообщение HTTP Request будет отправлено на веб-сервер без каких-либо задержек на стороне клиента.Скорее всего, запросы будут отправляться на сервер последовательно, но я не думаю, что это гарантировано.Я думаю, что вы думаете с точки зрения многопоточности ...

Синхронные вызовы могут вызвать задержку на стороне клиента, в то время как интерпретатор JavaScript браузера ожидает ответа AJAX.

Для краткого примера, скажем, у вас есть вызов AJAX, который выбирает налоговую ставку для данного штата США.Если бы это был синхронный вызов, то инструмент извлечения остановил бы расчет, и любое взаимодействие пользователя с Javascript не привело бы к ответу, пока не был получен ответ AJAX (с налоговой ставкой).

В вышеописанной асинхронной ситуации вы можете определить функцию обратного вызова, которая продолжит вычислять окончательную цену проверки после получения ответа AJAX.

0 голосов
/ 22 апреля 2011

Я считаю, что фактическая проблема с параллельным выполнением, наблюдаемая MGM, была упущена потому что он выполнил регистрацию времени как часть "успеха" функции. Он взял общие объяснения об асине. характер запросов в качестве ответа, однако, здесь есть проблема.

Посмотрите на фрагмент ниже:

    $(function() {
        $(".dd").each(function() {
            var obj = $(this);
            $.get("test.txt", function(data) {
                obj.html(data);
            });
        });
    });

Он загружает файл (асинхронно, как я ожидал) и отображает его (конечно же, синхронно).

Однако код выполняется по-разному во время загрузки первой страницы и при обновлении страницы. Я отслеживаю запросы к серверу, используя Firebug Net Panel в Firefox 4.0 на Windows. На первой странице загрузки (или при обновлении с помощью Ctrl-F5) я вижу на панели «Сеть» что несколько запросов к «test.txt» запускаются одновременно, и активность сети в основном перекрывается.

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

(изображение: начальная загрузка) (http://i.stack.imgur.com/nSFld.gif)

Это совершенно другая история, когда пользователь нажимает клавишу F5, чтобы обновить страницу. Внезапно параллелизм исчез.
И одна и та же веб-страница загружает «test.txt» один за другим.

(изображение: последующее обновление) (http://i.stack.imgur.com/7cYfM.gif) Становится еще яснее, если я заменю отображение данных (obj.html (data);) простым предупреждением: alert (data); При начальной загрузке страницы я получаю несколько предупреждений одновременно на экране. Последующие обновления (F5) наглядно демонстрируют, что пока одно предупреждающее сообщение отображается на экране, другое загрузка произведена (я могу удалить файл, чтобы увидеть, что «$ .get» не работает).

Так что на самом деле $ .get не выполняет асинхронный вызов. звонки на сервер.

Есть идеи, почему это происходит?

P.S. Извините, система не позволяет мне публиковать изображения.

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