Подождите, пока все запросы JQuery Ajax будут выполнены?

560

Как сделать функцию до тех пор, пока все запросы jQuery Ajax не будут выполнены внутри другой функции?

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

  • 0
    Как вы называете ваши оригинальные запросы AJAX?
  • 2
    Что вы подразумеваете под "сделано"? Я понимаю это как "все запросы были выполнены успешно или нет" (решены или отклонены). Но вы можете иметь в виду «все запросы успешно завершены» (решены). увидеть все варианты в api.jquery.com/category/deferred-object
Теги:

23 ответа

764
Лучший ответ

jQuery теперь определяет функцию when для этой цели.

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

Это означает, что если вы хотите инициировать (например) четыре запроса ajax, а затем выполнить действие, когда они будут выполнены, вы можете сделать что-то вроде этого:

$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){
    // the code here will be executed when all four ajax requests resolve.
    // a1, a2, a3 and a4 are lists of length 3 containing the response text,
    // status, and jqXHR object for each of the four ajax calls respectively.
});

function ajax1() {
    // NOTE:  This function must return the value 
    //        from calling the $.ajax() method.
    return $.ajax({
        url: "someUrl",
        dataType: "json",
        data:  yourJsonData,            
        ...
    });
}

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

Если вы не знаете заранее, сколько аргументов ajax вам нужно подождать (т.е. Вы хотите использовать переменное количество аргументов), это все равно можно сделать, но это немного сложнее. См. " Передать" в массиве "Отложенные" до $.when() (и, возможно, jQuery. При устранении неполадок с переменным числом аргументов).

Если вам нужно более глубокое управление режимами сбоев сценариев ajax и т.д., Вы можете сохранить объект, возвращаемый .when() - это объект jQuery Promise, охватывающий все исходные запросы ajax. Вы можете позвонить .then() или .fail() чтобы добавить подробные обработчики успеха/отказа.

  • 19
    Это действительно лучшее решение, но оно требует небольшого объяснения для непосвященных.
  • 3
    Спасибо за отзыв - я добавил немного больше деталей.
Показать ещё 23 комментария
278

Если вы хотите дождаться завершения всех запросов ajax в вашем документе, независимо от того, сколько из них существует, просто используйте событие $.ajaxStop таким образом:

  $(document).ajaxStop(function () {
      // 0 === $.active
  });

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

$.ajaxStop здесь также может быть привязан к любому узлу HTML который, по вашему мнению, может быть изменен ajax.

Опять же, цель этого обработчика - знать, когда нет активного ajax чтобы не очистить или не перезагрузить что-то.

PS Если вы не против использования синтаксиса ES6, вы можете использовать Promise.all для известных методов ajax. Пример:

Promise.all([ajax1(), ajax2()]).then(() => {
 // all requests finished successfully
}).catch(() => {
 // all requests finished but one or more failed
})

Интересным моментом здесь является то, что он работает как с Promises и с запросами $.ajax. Вот jsFiddle, демонстрирующий последний.

  • 18
    Хорошо - это должно иметь больше голосов
  • 14
    +1 Гораздо лучше, чем другие ответы, если вам приходится иметь дело со сторонними скриптами с анонимными обратными вызовами / замыканиями.
Показать ещё 13 комментариев
31

Я нашел хороший ответ gnarf, который я точно искал:)

jQuery ajaxQueue

//This handles the queues    
(function($) {

  var ajaxQueue = $({});

  $.ajaxQueue = function(ajaxOpts) {

    var oldComplete = ajaxOpts.complete;

    ajaxQueue.queue(function(next) {

      ajaxOpts.complete = function() {
        if (oldComplete) oldComplete.apply(this, arguments);

        next();
      };

      $.ajax(ajaxOpts);
    });
  };

})(jQuery);

Затем вы можете добавить запрос ajax в очередь следующим образом:

$.ajaxQueue({
        url: 'page.php',
        data: {id: 1},
        type: 'POST',
        success: function(data) {
            $('#status').html(data);
        }
    });
  • 37
    Похоже, вы забыли дать правильную атрибуцию этому ответу , я его добавил.
19

Используйте событие ajaxStop.

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

Из jQuery doc:

$("#loading").ajaxStop(function() {
  $(this).hide();
});

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

  • 2
    Я думаю, это, безусловно, лучшее решение ... ура
  • 3
    Это предполагает, что вы знаете, что на странице не будет никаких других запросов AJAX, не очень хорошее предположение
Показать ещё 2 комментария
19

ПРИМЕЧАНИЕ.. В приведенных выше ответах используются функциональные возможности, которых не было в то время, когда этот ответ был написан. Я рекомендую использовать jQuery.when() вместо этих подходов, но я оставляю ответ в исторических целях.

-

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

var semaphore  = 0,     // counting semaphore for ajax requests
    all_queued = false; // bool indicator to account for instances where the first request might finish before the second even starts

semaphore++;
$.get('ajax/test1.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test2.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test3.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test4.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

// now that all ajax requests are queued up, switch the bool to indicate it
all_queued = true;

Если вы хотите, чтобы это работало как {async: false}, но вы не хотели блокировать браузер, вы могли бы сделать то же самое с очередью jQuery.

var $queue = $("<div/>");
$queue.queue(function(){
    $.get('ajax/test1.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test2.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test3.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test4.html', function(data) {
        $queue.dequeue();
    });
});
  • 10
    Кажется, это слишком усложнит тривиальную проблему.
  • 2
    Это действительно не все так сложно. Подсчет семафоров является распространенным механизмом в CS. Однако, если вы предпочитаете, пример с использованием очередей jQuery будет работать без необходимости реализовывать семафор самостоятельно.
Показать ещё 7 комментариев
7

Небольшое обходное решение выглядит примерно так:

// Define how many Ajax calls must be done
var ajaxCalls = 3;
var counter = 0;
var ajaxCallComplete = function() {
    counter++;
    if( counter >= ajaxCalls ) {
            // When all ajax calls has been done
        // Do something like hide waiting images, or any else function call
        $('*').css('cursor', 'auto');
    }
};

var loadPersons = function() {
        // Show waiting image, or something else
    $('*').css('cursor', 'wait');

    var url = global.ctx + '/loadPersons';
    $.getJSON(url, function(data) {
            // Fun things
    })
    .complete(function() { **ajaxCallComplete();** });
};

var loadCountries = function() {
    // Do things
    var url = global.ctx + '/loadCountries';
    $.getJSON(url, function(data) {
            // Travels
    })
    .complete(function() { **ajaxCallComplete();** });
};

var loadCities = function() {
    // Do things
    var url = global.ctx + '/loadCities';
    $.getJSON(url, function(data) {
            // Travels
    })
    .complete(function() { **ajaxCallComplete();** });
};

$(document).ready(function(){
    loadPersons();
    loadCountries();
    loadCities();
});

Надежда может быть полезна...

  • 0
    В то время как другие ответы технически лучше, так как их легче понять, мне очень нравится этот. Ницца!
  • 0
    Лучший обходной путь
6

javascript основан на событиях, поэтому вы никогда не должны ждать, а установите привязки/обратные вызовы

Вероятно, вы можете просто использовать методы успеха/завершения jquery.ajax

Или вы можете использовать . ajaxComplete:

$('.log').ajaxComplete(function(e, xhr, settings) {
  if (settings.url == 'ajax/test.html') {
    $(this).text('Triggered ajaxComplete handler.');
    //and you can do whatever other processing here, including calling another function...
  }
});

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

1

Я использую проверку размера, когда вся загрузка ajax завершена

function get_ajax(link, data, callback) {
    $.ajax({
        url: link,
        type: "GET",
        data: data,
        dataType: "json",
        success: function (data, status, jqXHR) {
            callback(jqXHR.status, data)
        },
        error: function (jqXHR, status, err) {
            callback(jqXHR.status, jqXHR);
        },
        complete: function (jqXHR, status) {
        }
    })
}

function run_list_ajax(callback){
    var size=0;
    var max= 10;
    for (let index = 0; index < max; index++) {
        var link = 'http://api.jquery.com/ajaxStop/';
        var data={i:index}
        get_ajax(link,data,function(status, data){
            console.log(index)
            if(size>max-2){
                callback('done')
            }
            size++
            
        })
    }
}

run_list_ajax(function(info){
    console.log(info)
})
<script src="/jquery.min.js"></script>
  • 0
    превью вашего примера.
1

$.when не работает для меня, callback(x) вместо return x работал, как описано здесь: https://stackoverflow.com/questions/13455134/javascript-doesnt-seem-to-wait-for-return-values

1

Я настоятельно рекомендую использовать $. when(), если вы начинаете с нуля.

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

Мы можем легко воспользоваться функциями jQuery .data, .on и .trigger, которые были частью jQuery с тех пор, как навсегда.

Codepen

Хороший материал о моем решении:

  • очевидно, что обратный вызов точно зависит от

  • функция triggerNowOrOnLoaded не заботится, были ли данные уже загружены или мы все еще ждем его

  • его легко подключить к существующему коду

$(function() {

  // wait for posts to be loaded
  triggerNowOrOnLoaded("posts", function() {
    var $body = $("body");
    var posts = $body.data("posts");

    $body.append("<div>Posts: " + posts.length + "</div>");
  });


  // some ajax requests
  $.getJSON("https://jsonplaceholder.typicode.com/posts", function(data) {
    $("body").data("posts", data).trigger("posts");
  });

  // doesn't matter if the `triggerNowOrOnLoaded` is called after or before the actual requests 
  $.getJSON("https://jsonplaceholder.typicode.com/users", function(data) {
    $("body").data("users", data).trigger("users");
  });


  // wait for both types
  triggerNowOrOnLoaded(["posts", "users"], function() {
    var $body = $("body");
    var posts = $body.data("posts");
    var users = $body.data("users");

    $body.append("<div>Posts: " + posts.length + " and Users: " + users.length + "</div>");
  });

  // works even if everything has already loaded!
  setTimeout(function() {

    // triggers immediately since users have been already loaded
    triggerNowOrOnLoaded("users", function() {
      var $body = $("body");
      var users = $body.data("users");

      $body.append("<div>Delayed Users: " + users.length + "</div>");
    });

  }, 2000); // 2 seconds

});

// helper function
function triggerNowOrOnLoaded(types, callback) {
  types = $.isArray(types) ? types : [types];

  var $body = $("body");

  var waitForTypes = [];
  $.each(types, function(i, type) {

    if (typeof $body.data(type) === 'undefined') {
      waitForTypes.push(type);
    }
  });

  var isDataReady = waitForTypes.length === 0;
  if (isDataReady) {
    callback();
    return;
  }

  // wait for the last type and run this function again for the rest of the types
  var waitFor = waitForTypes.pop();
  $body.on(waitFor, function() {
    // remove event handler - we only want the stuff triggered once
    $body.off(waitFor);

    triggerNowOrOnLoaded(waitForTypes, callback);
  });
}
<script src="/jquery.min.js"></script>

<body>Hi!</body>
1

Также вы можете использовать async.js.

Я думаю, что это лучше, чем $., потому что вы можете объединить все виды асинхронных вызовов, которые не поддерживают promises из коробки, такие как таймауты, вызовы SqlLite и т.д., а не просто запросы ajax.

1

На основе ответа @BBonifield я написал функцию утилиты, так что логика семафора не распространяется во всех вызовах ajax.

untilAjax - это функция утилиты, которая вызывает функцию обратного вызова, когда все ajaxCalls завершены.

ajaxObjs - это массив объектов установки ajax [http://api.jquery.com/jQuery.ajax/].

fn - функция обратного вызова

function untilAjax(ajaxObjs, fn) {
  if (!ajaxObjs || !fn) {
    return;
  }
  var ajaxCount = ajaxObjs.length,
    succ = null;

  for (var i = 0; i < ajaxObjs.length; i++) { //append logic to invoke callback function once all the ajax calls are completed, in success handler.
    succ = ajaxObjs[i]['success'];
    ajaxObjs[i]['success'] = function(data) { //modified success handler
      if (succ) {
        succ(data);
      }
      ajaxCount--;
      if (ajaxCount == 0) {
        fn(); //modify statement suitably if you want 'this' keyword to refer to another object
      }
    };
    $.ajax(ajaxObjs[i]); //make ajax call
    succ = null;
  };

Пример: функция doSomething использует untilAjax.

function doSomething() {
  // variable declarations
  untilAjax([{
    url: 'url2',
    dataType: 'json',
    success: function(data) {
      //do something with success data
    }
  }, {
    url: 'url1',
    dataType: 'json',
    success: function(data) {
      //do something with success data
    }
  }, {
    url: 'url2',
    dataType: 'json',
    success: function(response) {
      //do something with success data
    }
  }], function() {
    // logic after all the calls are completed.
  });
}
0

Как уже упоминалось в других ответах, вы можете использовать ajaxStop() чтобы дождаться завершения всех запросов ajax.

$(document).ajaxStop(function() {
     // This function will be triggered every time an ajax is requested and completed
});

Но если вы хотите сделать это для конкретного запроса ajax() лучшее, что вы можете сделать, это использовать метод complete() внутри определенного запроса ajax:

$.ajax({
    type: "POST",
    url: "someUrl",
    success: function(data) {
        // This function will be triggered when ajax returns a 200 status code (success)
    },
    complete: function() {
        // This function will be triggered always, when ajax request is completed, even it fails/returns other status code
    },
    error: function() {
        // This will be triggered when ajax request fail.
    }
});
0

Чтобы расширить ответ Алекса, у меня есть пример с переменными аргументами и обещаниями. Я хотел загрузить изображения через ajax и отобразить их на странице после того, как они все загрузятся.

Для этого я использовал следующее:

let urlCreator = window.URL || window.webkitURL;

// Helper function for making ajax requests
let fetch = function(url) {
    return $.ajax({
        type: "get",
        xhrFields: {
            responseType: "blob"
        },
        url: url,
    });
};

// Map the array of urls to an array of ajax requests
let urls = ["https://placekitten.com/200/250", "https://placekitten.com/300/250"];
let files = urls.map(url => fetch(url));

// Use the spread operator to wait for all requests
$.when(...files).then(function() {
    // If we have multiple urls, then loop through
    if(urls.length > 1) {
        // Create image urls and tags for each result
        Array.from(arguments).forEach(data => {
            let imageUrl = urlCreator.createObjectURL(data[0]);
            let img = '<img src=${imageUrl}>';
            $("#image_container").append(img);
        });
    }
    else {
        // Create image source and tag for result
        let imageUrl = urlCreator.createObjectURL(arguments[0]);
        let img = '<img src=${imageUrl}>';
        $("#image_container").append(img);
    }
});

Обновлено для работы с одним или несколькими URL-адресами: https://jsfiddle.net/euypj5w9/

0

Я нашел простой способ, используя shift()

function waitReq(id)
{
  jQuery.ajax(
  {
    type: 'POST',
    url: ajaxurl,
    data:
    {
      "page": id
    },
    success: function(resp)
    {
      ...........
      // check array length if not "0" continue to use next array value
      if(ids.length)
      {
        waitReq(ids.shift()); // 2
      )
    },
    error: function(resp)
    {
      ....................
      if(ids.length)
      {
        waitReq(ids.shift());
      )
    }
  });
}

var ids = [1, 2, 3, 4, 5];    
// shift() = delete first array value (then print)
waitReq(ids.shift()); // print 1
0

Если вам нужно что-то простое; один раз и закончил обратный вызов

        //multiple ajax calls above
        var callback = function () {
            if ($.active !== 0) {
                setTimeout(callback, '500');
                return;
            }
            //whatever you need to do here
            //...
        };
        callback();
  • 3
    это может генерировать бесконечный цикл!
  • 1
    Это бесконечный цикл? Когда? Когда AJAX никогда не вернется?
0

Мое решение выглядит следующим образом

var request;
...
'services': {
  'GetAddressBookData': function() {
    //This is the primary service that loads all addressbook records 
    request = $.ajax({
      type: "POST",
      url: "Default.aspx/GetAddressBook",
      contentType: "application/json;",
      dataType: "json"
    });
  },

  ...

  'apps': {
    'AddressBook': {
      'data': "",
      'Start': function() {
          ...services.GetAddressBookData();
          request.done(function(response) {
            trace("ajax successful");
            ..apps.AddressBook.data = response['d'];
            ...apps.AddressBook.Filter();
          });
          request.fail(function(xhr, textStatus, errorThrown) {
            trace("ajax failed - " + errorThrown);
          });

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

0

Я встретил эту проблему и создал общий плагин jquery_counter, чтобы решить эту проблему: https://bitbucket.org/stxnext/jquery_counter/

  • 0
    Ссылка не работает.
  • 0
    Исправил ссылку
0

Посмотрите на мое решение:

1.Вставьте эту функцию (и переменную) в файл javascript:

var runFunctionQueue_callback;

function runFunctionQueue(f, index, callback) {

  var next_index = index + 1

  if (callback !== undefined) runFunctionQueue_callback = callback;

  if (f[next_index] !== undefined) {
    console.log(index + ' Next function avalaible -> ' + next_index);
    $.ajax({
      type: 'GET',
      url: f[index].file,
      data: (f[index].data),
      complete: function() {
        runFunctionQueue(f, next_index);
      }
    });
  } else {
    console.log(index + ' Last function');
    $.ajax({
      type: 'GET',
      url: f[index].file,
      data: (f[index].data),
      async: false,
      complete: runFunctionQueue_callback
    });
  }
}

2.Buil массив с вашими запросами, например:

var f = [
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}}
        ];

3.Создать функцию обратного вызова:

function Function_callback() {
  alert('done');
}

4. Запустите функцию runFunctionQueue с параметрами:

runFunctionQueue(f, 0, QuestionInsert_callback);
// first parameter: array with requests data
// second parameter: start from first request
// third parameter: the callback function
0

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

Например:

jQuery.ajax({ 
    async: false,
    //code
});
  • 41
    Стоит отметить, что использование {async: false} может временно заблокировать браузер. api.jquery.com/jQuery.ajax
  • 1
    Именно так! Таким образом, вы узнаете, что в конце функции, которая вызывает все запросы AJAX, все они завершены.
Показать ещё 19 комментариев
-1

Самое элегантное решение, которое я нашел, которое лучше всего работает с несколькими асинхронными операциями, в отсутствие библиотеки, такой как jQuery или объект, подобный jQuery .when(), заключается в том, чтобы каждый обработчик выполнения Promise приложил обработчик выполнения к одному из других Promises, как это (предполагая, что обещание1, обещание2 и обещание3 являются экземплярами Promise неизвестного состояния):

promise1.then(function(value)
{
    promise2.then(function(value2)
    {
        promise3.then(function(value3)
        {
            doSomethingWithValues(value1, value2, value3);
        }
    }
});

Это работает, потому что выполненные/отклоненные обратные вызовы немедленно срабатывают, если они прикреплены после того, как обещание выполнено или отклонено. Поэтому, даже если promise3 выполняется в первую очередь, его обратный вызов выполнения не будет выполняться до тех пор, пока он не будет присоединен, что не произойдет до тех пор, пока promise1 и promise2 не будут выполнены. Недостатком этого подхода является то, что вложенные выражения функций могут быть немного запутанными. С небольшим количеством рефакторинга мы можем устранить необходимость вложенных функций;

var value1, value2;

function handlePromise1Fulfillment(value)
{
    value1 = value;

    promise2.then(handlePromise2Fulfillment);
}

function handlePromise2Fulfillment(value)
{
    value2 = value;

    promise3.then(handlePromise3Fulfillment);
}

function handlePromise3Fulfillment(value)
{
    doSomethingWithValues(value1, value2, value);
}

promise1.then(handlePromise1Fulfillment);

С этой идиомой мы можем построить неограниченные конъюнкции Promises, не уменьшая удобочитаемость до ужасной степени. И с этой идиомой мы имеем основание для (простой, неполной) when() функции нашей собственной:

function when()
{
    var fulfillmentHandlers = [];
    var values = [];
    var promises = arguments;

    return new Promise(function(resolve, reject)
    { 
        fulfillmentHandlers.push(function(value)
        {
            values.push(value);
            resolve(values.reverse());
        });

        var i;
        // The i declaration in the for loop would be hoisted outside of the loop, but we might as well make this explicit
        for (i = 0; i < promises.length - 1; i++)
        {   
             fulfillmentHandlers[i + 1] = (function(iterator) 
             {
                 return function(value)
                 {
                      values.push(value);
                      promises[iterator].then(fulfillmentHandlers[iterator]);
                 }
             })(i);
        }

        promises[i].then(fulfillmentHandlers[i]);
    });
}

var promise1 = new Promise(function(resolve, reject)
{
    setTimeout(function() { resolve('JavaScript '); }, 5000);
});

var promise2 = new Promise(function(resolve)
{
    setTimeout(function() { resolve('is '); }, 4000);
});

var promise3 = new Promise(function(resolve)
{
    setTimeout(function() { resolve('fun!'); }, 3000);
});

when(promise1, promise2, promise3).then(function(values)
{
    console.log(values[0] + values[1] + values[2]);
});
-2

Решение, данное Алексом, отлично работает. Такая же концепция, но использование ее немного по-другому (когда количество вызовов неизвестно заранее)

http://garbageoverflow.blogspot.com/2014/02/wait-for-n-or-multiple-or-unknown.html

-3

Попробуйте этот путь. сделайте цикл внутри java script, чтобы ждать завершения вызова ajax.

function getLabelById(id)
{
    var label = '';
    var done = false;
    $.ajax({
       cache: false,
       url: "YourMvcActionUrl",
       type: "GET",
       dataType: "json",
       async: false,
       error: function (result) {
         label='undefined';
         done = true;
        },
       success: function (result) {
            label = result.Message;
            done = true;
        }
     });

   //A loop to check done if ajax call is done.
   while (!done)
   {
      setTimeout(function(){ },500); // take a sleep.
   }

    return label;
}
  • 1
    Ваш setTimeout() НЕ take a sleep . В этом случае вы просто блокируете все вкладки до тех пор, пока done станет истинным.
  • 1
    Я думаю, что эта тема просит: «Подождите, пока не будут выполнены все запросы jQuery Ajax».
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню