Подтвердить что ты не робот

Как сделать все вызовы AJAX последовательными?

Я использую jQuery. И мне не нужны параллельные вызовы AJAX для моего приложения, каждый вызов должен ждать предыдущего перед запуском. Как его реализовать? Есть помощник?

UPDATE Если есть какая-либо синхронная версия XMLHttpRequest или jQuery.post, я хотел бы знать. Но последовательный!= Синхронный, и я хотел бы получить асинхронное и последовательное решение.

4b9b3361

Ответ 1

Там гораздо лучший способ сделать это, чем использовать синхронные вызовы ajax. Jquery ajax возвращает отложенное значение, поэтому вы можете просто использовать цепочку соединений, чтобы удостовериться, что каждый вызов ajax заканчивается до следующего запуска. Здесь рабочий пример с более глубоким примером можно играть с jsfiddle.

// How to force async functions to execute sequentially 
// by using deferred pipe chaining.

// The master deferred.
var dfd = $.Deferred(),  // Master deferred
    dfdNext = dfd; // Next deferred in the chain
    x = 0, // Loop index
    values = [], 

    // Simulates $.ajax, but with predictable behaviour.
    // You only need to understand that higher 'value' param 
    // will finish earlier.
    simulateAjax = function (value) {
        var dfdAjax = $.Deferred();

        setTimeout(
            function () {
                dfdAjax.resolve(value);
            },
            1000 - (value * 100)
        );

        return dfdAjax.promise();
    },

    // This would be a user function that makes an ajax request.
    // In normal code you'd be using $.ajax instead of simulateAjax.
    requestAjax = function (value) {
        return simulateAjax(value);
    };

// Start the pipe chain.  You should be able to do 
// this anywhere in the program, even
// at the end,and it should still give the same results.
dfd.resolve();

// Deferred pipe chaining.
// What you want to note here is that an new 
// ajax call will not start until the previous
// ajax call is completely finished.
for (x = 1; x <= 4; x++) {

    values.push(x);

    dfdNext = dfdNext.pipe(function () {
        var value = values.shift();
        return requestAjax(value).
            done(function(response) {
                // Process the response here.

            });

    });

}

Некоторые люди прокомментировали, что понятия не имеют, что делает код. Чтобы понять это, вам сначала нужно понять javascript promises. Я уверен, что promises скоро станет родной функцией языка JavaScript, так что это должно дать вам хороший стимул для изучения.

Ответ 2

У вас есть два варианта, о которых я могу думать. Один из них - связать их посредством обратных вызовов. Другой способ - сделать вызовы синхронными, а не асинхронными.

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

Чтобы сделать синхронный вызов, вы установите для параметра async в вызове Ajax значение false. См. Документацию на http://docs.jquery.com/Ajax/jQuery.ajax#options (нажмите кнопку "Параметры", чтобы увидеть их).

Ответ 3

Вы можете дать описательный javascript попробовать http://www.neilmix.com/narrativejs/doc/

Я никогда не использовал его сам. Если бы я хотел сделать это, я бы установил какую-то абстракцию для цепочки асинхронных действий. Как говорили другие, синхронная версия объекта ajax блокирует события от обработки во время ожидания ответа. Это заставляет браузер выглядеть как замороженный, пока не получит ответ.

Ответ 4

Посмотрите на это: http://docs.jquery.com/Ajax/jQuery.ajax (щелкните вкладку "Параметры" ).

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

ИЗМЕНИТЬ: ОК, с вашим обновлением яснее, что вы хотите достичь;)

Итак, ваш код может выглядеть так:

    $.getJSON("http://example.com/jsoncall", function(data) {
        process(data);
        $.getJSON("http://example.com/jsoncall2", function (data) {
            processAgain(data);
            $.getJSON("http://example.com/anotherjsoncall", function(data) {
                processAgainAndAgain(data);
            });
        });
    });

Таким образом, второй вызов будет выдаваться только тогда, когда ответ на первый вызов будет получен и обработан, а третий вызов будет выдан только тогда, когда ответ на второй вызов будет получен и обработан. Этот код предназначен для getJSON, но он может быть адаптирован к $.ajax.

Ответ 5

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

Насколько мне известно, для этого недостаточно помощника, но вы можете сделать что-то похожее на FIFO обратного вызова.

Ответ 6

Установите для параметра async значение false, например,

$.ajax({ async: false /*, your_other_ajax_options_here */ });

Ссылка: Ajax/jQuery.ajax

Ответ 8

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

Ответ 9

(async () => { 
  for(f of ['1.json','2.json','3.json']){
    var json = await $.getJSON(f);
    console.log(json)
 };
})()
  1. запрашивает 3 json файла с помощью jQuery ajax-вызовов
  2. процесс в последовательности (не параллельно) с ожиданием
  3. работает в Chrome/Firefox/Edge (по состоянию на 30.01.2008)

больше в MDN

Ответ 10

Вы можете использовать обещание, чтобы сделать ajax-вызовы последовательными. Используя метод массива push и pop обещание, последовательные вызовы ajax будут намного проще.

var promises = [Promise.resolve()];

function methodThatReturnsAPromise(id) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: 'https://jsonplaceholder.typicode.com/todos/'+id,
      dataType:'json',
      success: function(data)
      {
        console.log("Ajax Request Id"+id);
        console.log(data);
        resolve();
      }
    });
  });
} 

function pushPromise(id)
{
  promises.push(promises.pop().then(function(){
    return methodThatReturnsAPromise(id)}));
}


pushPromise(1);
pushPromise(3);
pushPromise(2);

Ответ 11

Как насчет использования событий Node.js?

var EventEmitter = require('events').EventEmitter;
var eventEmitter = new EventEmitter();
var $ = require('jquery');

var doSomething = function (responseData) {
  var nextRequestData = {};
  // do something with responseData
  return nextRequestData;
};

// ajax requests
var request1 = $.ajax;
var request2 = $.ajax;
var requests = [request1, request2];

eventEmitter.on('next', function (i, requestData) {
  requests[i](requestData).then(
    function (responseData) {
      console.log(i, 'request completed');
      if (i+1 < requests.length) {
        var nextRequestData = doSomething(responseData);
        eventEmitter.emit('next', i+1, nextRequestData);
      }
      else {
        console.log('completed all requests');
      }
    },
    function () {
      console.log(i, 'request failed');
    }
  );
});

var data = {
  //data to send with request 1
};
eventEmitter.emit('next', 0, data);

Ответ 12

последовательный!= синхронный, и я хотел бы получить асинхронное и последовательное решение

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

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