어떻게 사용하는 경우 다음을 보낼 파일 업로드에서 순차적으로는 기능 또한 이연 약속이 있습니까?
-
26-12-2019 - |
문제
내가 하려는 업로드 파일의 배열을 사용하여 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!')});
불행하게도,할 수 없었고 많은 파일을 업로드하기 전에 나는 리디렉션 페이지.
내가 다양한 시도 직접 솔루션에 이렇게 하는 방법.지금까지 아무것도 작동하지 않습니다.알려 주시기 바랍니다.
일부 코드가 잘린 공간이 절약됩니다.
해결책
귀하의 모든 약속은 병렬과하지 연속적이다.
약속을 나타내는 이미 실행 작업입니다.약속에서 JavaScript 과는 달리,C#작업 또는 다른 추상화는 이미 시작했다.방법을 대표하는 작업이 시작되지 않은 반환하는 함수입니 약속입니다.
이 promises[i]
이 약속을 할 때 promise.then(object)
그것은 추가하지 않습니다.다음 처리기는 하지만 오히려오. .then
모두 무시하는 인수하지 않은 기능입니다.
이것은 왜 그것을 반환하기,그것은 즉시 반환하는 첫 번째 약속을 충족.당신은 또한 당신이 필요하지 않은 .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);
참고,지금 작업이 각각 기능 을 반환하는 약속을 통해 파일을 업로드 할 수 있습니다.그들은 그 약속입니다.
지금,당신이 할 수있는 체인:
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;
당신은 또한 현재 사용하지 않을 때,이후 반환 단일 약속입니다.나는 가정이 필요하지 않은 실제 여기 결과(지만 알고 있는 성공/실패).
당신은 단순히 하:
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;
}