gpt4 book ai didi

javascript - 如何在也是延迟 promise 的函数中使用 when then 顺序发送文件上传?

转载 作者:搜寻专家 更新时间:2023-11-01 04:31:47 25 4
gpt4 key购买 nike

我打算使用 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com