簡體   English   中英

如何等待jQuery ajax請求在循環中完成?

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

我有那個代碼:

for (var i = 0; i < $total_files; i++) {
  $.ajax({
    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');
    }
  });
}

它上傳的圖片非常好,但問題是我找不到逐個上傳圖片的方法,我試圖將選項async設置為false但它凍結了網頁瀏覽器,直到所有圖片都上傳不是我的想要,我想以某種方式模擬這個“async:false”選項來執行相同的操作但不凍結Web瀏覽器。

這該怎么做 ?

您可以創建一個承諾數組,以便在解決所有承諾后,您可以運行all done代碼。

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

使用每個調用填充數組,並在完成上一個調用后調用下一個項目。

你可以嘗試這樣的事情:

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


        }

    }

只需使用syncUpload.upload(NUMBER_OF_IMAGES)調用它;

對於jQuery 3.x +和支持本機Promise現代瀏覽器, Promise.all可以這樣使用:

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

如果您的文件已經存儲在列表中,那么您可以使用map而不是循環。

var fileList = [/*... list of files ...*/];

Promise.all(fileList.map(file => $.ajax({
      /* your ajax config*/
})))
.then(responseList => {
   console.dir(responseList)
})

我會嘗試jQuery.when所以你仍然可以使用異步調用但延遲,如:

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

編輯 :ajax迭代應該在$.when .when之外完成並按照charlietfl的回答推薦到數組中。 您可以使用(異步)ajax調用並將其推遲到$.when .when中,但請參閱JSFIDDLE

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM