Wait until all jQuery Ajax requests are done?

后端 未结 21 1842
离开以前
离开以前 2020-11-21 04:39

How do I make a function wait until all jQuery Ajax requests are done inside another function?

In short, I need to wait for all Ajax requests to be done before I exe

相关标签:
21条回答
  • 2020-11-21 05:16

    NOTE: The above answers use functionality that didn't exist at the time that this answer was written. I recommend using jQuery.when() instead of these approaches, but I'm leaving the answer for historical purposes.

    -

    You could probably get by with a simple counting semaphore, although how you implement it would be dependent on your code. A simple example would be something like...

    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;
    

    If you wanted this to operate like {async: false} but you didn't want to lock the browser, you could accomplish the same thing with a jQuery queue.

    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();
        });
    });
    
    0 讨论(0)
  • 2020-11-21 05:16

    javascript is event-based, so you should never wait, rather set hooks/callbacks

    You can probably just use the success/complete methods of jquery.ajax

    Or you could use .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...
      }
    });
    

    though youy should post a pseudocode of how your(s) ajax request(s) is(are) called to be more precise...

    0 讨论(0)
  • 2020-11-21 05:18

    A little workaround is something like this:

    // 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();
    });
    

    Hope can be useful...

    0 讨论(0)
  • 2020-11-21 05:18

    jQuery allows you to specify if you want the ajax request to be asynchronous or not. You can simply make the ajax requests synchronous and then the rest of the code won't execute until they return.

    For example:

    jQuery.ajax({ 
        async: false,
        //code
    });
    
    0 讨论(0)
  • 2020-11-21 05:18

    My solution is as follows

    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);
              });
    

    Worked quite nicely. I've tried a lot of different ways of doing this, but I found this to be the simplest and most reusable. Hope it helps

    0 讨论(0)
  • 2020-11-21 05:22

    To expand upon Alex's answer, I have an example with variable arguments and promises. I wanted to load images via ajax and display them on the page after they all loaded.

    To do that, I used the following:

    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);
        }
    });
    

    Updated to work for either single or multiple urls: https://jsfiddle.net/euypj5w9/

    0 讨论(0)
提交回复
热议问题