- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我打算使用 jQuery 上传一组文件。
此意图包含在名为 uploadFilesUsingAjax()
的函数中;
var uploadFilesPromise = uploadFilesUsingAjax();
$.when(uploadFilesPromise).done(function (uploadFilesAjaxResult) {
// redirect to success page...
我需要等待所有文件上传成功,然后再做其他事情。
在 uploadFilesUsingAjax()
中,
我的代码是这样写的
function uploadFilesUsingAjax() {
var files = pages; // pages is a global variable which is an array of files
var url = "/users/" + currentUser.id + "/files.json";
var type = "POST";
console.info('files length:' + files.length);
if (files.length > 0) {
var promises=[];
for (var i = 0; i < files.length; i++) {
var data = new FormData();
var postData = {};
var file = files.getByIndex(i);
var key = i + 1;
if (typeof (file.id) !== "undefined" && file.id > 0) {
data.append(key, JSON.stringify(file));
} else {
data.append(key, file);
}
var request = $.ajax({
//this is the php file that processes the data
url: url,
//POST method is used
type: type,
//pass the data
data: data,
//Do not cache the page
cache: false,
xhr: function() {
// custom xhr
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload) { // check if upload property exists
myXhr.upload.addEventListener('progress',updatePagesProgress, false); // for handling the progress of the upload
}
return myXhr;
},
// DO NOT set the contentType and processData
// see http://stackoverflow.com/a/5976031/80353
contentType: false,
processData: false,
//success
success: function (json) {
// json is already an object thanks to cakephp code to serialize
//if POST is a success expect no errors
if (json.error == null && json.result != null) {
currentUser = json.result.User;
// error
} else {
alert(json.error);
}
}
});
promises.push( request);
}
var promise = promises[0];
for (var i = 1; i < promises.length; i++) {
promise = promise.then(promises[i]);
}
return promise.done(function () { console.log('all!')});
不幸的是,在我被重定向到成功页面之前,我无法上传很多文件。
我已经尝试了各种 StackOverflow 解决方案来了解如何做到这一点。到目前为止没有任何效果。请指教。
一些代码已被 chop 以节省空间。
最佳答案
你所有的 promise 都是并行的,而不是顺序的。
promise 代表一个已经在运行的任务。与 C# 任务或其他抽象不同,JavaScript 中的 promise 已经开始。表示尚未开始的任务的方法是返回一个 promise 的函数。
由于 promises[i]
已经是一个 promise - 当您执行 promise.then(object)
时,它不会添加 .then 处理程序,而是立即返回。 .then
忽略任何不是函数的参数。
这就是它提前返回的原因,它会在第一个 promise 履行后立即返回。您也不需要 .when
。创建一个创建上传过程的函数:
function createUploadTask(file,i){
return function(){
var data = new FormData();
var postData = {};
var file = files.getByIndex(i);
var key = i + 1;
if (typeof (file.id) !== "undefined" && file.id > 0) {
data.append(key, JSON.stringify(file));
} else {
data.append(key, file);
}
return $.ajax({...}); // return the promise
}
}
现在,您可以将文件映射到任务:
var tasks = files.map(createUploadTask);
请注意,现在任务是每个函数,它们通过文件上传返回 promise 。它们不是 promise 。
现在,您可以链接它们:
var p = tasks[0](); // start off the chain
for(var i = 1; i < tasks.length; i++){
// chain the next task, note, that we're passing a _function_ here
// when you return a promise from a `.then` it will fulfill when that promise
// fulfills, in our case the $.ajax
p = p.then(tasks[i]);
}
return p;
您现在也不需要使用 when,因为您返回了一个单个 promise。我假设您在这里不需要实际结果(但只需要知道成功/失败)。
你只需要做:
function uploadFilesUsingAjax() {
// settings
if(tasks.length === 0){
// a method MUST always either return either synchronously or asynchronously never
// both, always return a promise. Otherwise you get API hell.
var d = $.Deferred();
d.reject(new Error("Called uploadFiles with no files to upload"));
return d.promise;
}
tasks = pages.map(createUploadTask)
var p = tasks[0](); // call first one
for(var i = 1; i < tasks.length; i++) p = p.then(tasks[i]);
return p;
}
关于javascript - 如何在也是延迟 promise 的函数中使用 when then 顺序发送文件上传?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23065705/
我有以下正则表达式 /[a-zA-Z0-9_-]/ 当字符串只包含从 a 到z 大小写、数字、_ 和 -。 我的代码有什么问题? 能否请您向我提供一个简短的解释和有关如何修复它的代码示例? //var
我是一名优秀的程序员,十分优秀!