How to wait until jQuery ajax request finishes in a loop?

后端 未结 5 792
终归单人心
终归单人心 2020-11-27 02:42

I have that code :

for (var i = 0; i < $total_files; i++) {
  $.ajax({
    type: \'POST\',
    url: \'uploading.php\',
    context: $(this),
    dataType:         


        
相关标签:
5条回答
  • 2020-11-27 03:05

    You can create an array of promises so that once all promises are resolved you can run your all done code.

    var promises = [];
    for (var i = 0; i < $total_files; i++){ 
       /* $.ajax returns a promise*/      
       var request = $.ajax({
            /* your ajax config*/
       })
    
       promises.push( request);
    }
    
    $.when.apply(null, promises).done(function(){
       alert('All done')
    })
    

    DEMO

    0 讨论(0)
  • 2020-11-27 03:13

    I would try jQuery.when so you can still use asynchronous call but deferred, something like :

    jQuery(document).ready(function ($) {
        $.when(
            //for (var i = 0; i < $total_files; i++) {
                $.ajax({
                    // ajax code
                })
            //}
        ).done(function () {
            // perform after ajax loop is done
        }); 
    }); // ready
    

    EDIT : ajax iteration should be done outside $.when and pushed into an array as proposed by charlietfl's answer. You may use an (asynchronous) ajax call and defer it inside $.when though, see JSFIDDLE

    0 讨论(0)
  • 2020-11-27 03:22

    In one statement with jquery

    $.when.apply(null, $.map(/*input Array|jQuery*/, function (n, i) {
       return $.get(/* URL */, function (data) {
         /* Do something */
       });
    })).done(function () {
      /* Called after all ajax is done  */
    });
    
    0 讨论(0)
  • 2020-11-27 03:25

    For jQuery 3.x+ and modern browser that support native Promise, Promise.all could be used this way:

    var promises = [];
    for (var i = 0; i < $total_files; i++) {
       // jQuery returns a prom 
       promises.push($.ajax({
          /* your ajax config*/
       }))
    }
    
    Promise.all(promises)
    .then(responseList => {
       console.dir(responseList)
    })
    

    If your files are already stored in a list then you could use map instead of a loop.

    var fileList = [/*... list of files ...*/];
    
    Promise.all(fileList.map(file => $.ajax({
          /* your ajax config*/
    })))
    .then(responseList => {
       console.dir(responseList)
    })
    
    0 讨论(0)
  • 2020-11-27 03:31

    Populate an array with each call and call the next item when the previous is done.

    You could try something like that:

        window.syncUpload = {
    
            queue : [],
    
            upload : function(imagesCount) {
    
                var $total_files = imagesCount, data_string = "";
    
                /* Populates queue array with all ajax calls you are going to need */
                for (var i=0; i < $total_files; i++) {       
                    this.queue.push({
                        type: 'POST',
                        url: 'uploading.php',
                        context: $(this),
                        dataType: 'json',
                        cache: false,
                        contentType: false,
                        processData: false,
                        data: data_string,
                        success: function(datas) {
                        //does something
                        },
                        error: function(e){
                            alert('error, try again');
                        },
                        /* When the ajax finished it'll fire the complete event, so we
                           call the next image to be uploaded.
                        */
                        complete : function() {
                            this[0].uploadNext();
                        }
                    });
                }
    
                this.uploadNext();
            },
    
            uploadNext : function() {
                var queue = this.queue;
    
                /* If there's something left in the array, send it */
                if (queue.length > 0) {
                    /* Create ajax call and remove item from array */
                    $.ajax(queue.shift(0));
                }
    
    
            }
    
        }
    

    Just call it using syncUpload.upload(NUMBER_OF_IMAGES);

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