I have that code :
我有那个密码:
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');
}
});
}
It uploads images very well but the problem is that I can't find a way to upload the images one by one, I tried to put the option async to false but it freezes the web browser until all images are uploaded which is not what I want, I want to emulate somehow this "async : false" option to perform the same thing but without freezing the web browser.
它上传图片很好,但问题是,我不能找到一个方法来上传图片,我试图把选择异步虚假但它冻结web浏览器,直到所有的图片都上传这不是我想要的,我想效仿这“异步:假”选项来执行同样的事情但是没有冻结web浏览器。
How to do this ?
怎么做呢?
5 个解决方案
#1
54
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')
})
演示
#2
3
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);
只需使用syncUpload.upload(NUMBER_OF_IMAGES)调用它;
#3
3
For jQuery 3.x+ and modern browser that support native Promise
, Promise.all
could be used this way:
jQuery 3。支持本地承诺的x+和现代浏览器。所有这些都可以这样使用:
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.
如果您的文件已经存储在列表中,那么您可以使用map而不是循环。
var fileList = [/*... list of files ...*/];
Promise.all(fileList.map(file => $.ajax({
/* your ajax config*/
})))
.then(responseList => {
console.dir(responseList)
})
#4
2
I would try jQuery.when so you can still use asynchronous call but deferred, something like :
我将尝试jQuery。如果是这样,您仍然可以使用异步调用,但是延迟调用,比如:
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
编辑:ajax迭代应该在$之外完成。当,按charlietfl的建议推入数组。您可以使用(异步)ajax调用并将其延迟到$中。不过,当看到JSFIDDLE
#5
0
In one statement with jquery
在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 */
});
#1
54
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')
})
演示
#2
3
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);
只需使用syncUpload.upload(NUMBER_OF_IMAGES)调用它;
#3
3
For jQuery 3.x+ and modern browser that support native Promise
, Promise.all
could be used this way:
jQuery 3。支持本地承诺的x+和现代浏览器。所有这些都可以这样使用:
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.
如果您的文件已经存储在列表中,那么您可以使用map而不是循环。
var fileList = [/*... list of files ...*/];
Promise.all(fileList.map(file => $.ajax({
/* your ajax config*/
})))
.then(responseList => {
console.dir(responseList)
})
#4
2
I would try jQuery.when so you can still use asynchronous call but deferred, something like :
我将尝试jQuery。如果是这样,您仍然可以使用异步调用,但是延迟调用,比如:
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
编辑:ajax迭代应该在$之外完成。当,按charlietfl的建议推入数组。您可以使用(异步)ajax调用并将其延迟到$中。不过,当看到JSFIDDLE
#5
0
In one statement with jquery
在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 */
});