我想要做的是在服务器上传文件,然后获取上传文件的URL并进行预览。文件可以不止一个。为此,我写了以下代码:
let filesURL=[];
let promises=[];
if(this.state.files_to_upload.length>0) {
for(let i=0; i<this.state.files_to_upload.length; i++) {
promises.push(this.uploadFilesOnServer(this.state.files_to_upload[i]))
}
Promise.all(promises).then(function(result){
console.log(result);
result.map((file)=>{
filesURL.push(file);
});
});
console.log(filesURL);
}
const uploadedFilesURL=filesURL;
console.log(uploadedFilesURL);
console.log(filesURL);
为我提供Promise.all
返回的值
我只想在Promise.all
正确完成时才使用这些值。但是,我面临的问题是,console.log(uploadedFilesURL);
行首先考虑Promise.all
并且给我undefined
值。我认为我没有正确使用承诺,有人可以帮助我吗?>
uploadFileOnServer
代码为:
uploadFilesOnServer(file)
{
let files=[];
let file_id='';
const image=file;
getImageUrl().then((response) => {
const data = new FormData();
data.append('file-0', image);
const {upload_url} = JSON.parse(response);
console.log(upload_url);
updateProfileImage(upload_url, data).then ((response2) => {
const data2 = JSON.parse(response2);
file_id=data2;
console.log(file_id);
files.push(file_id);
console.log(files);
});
});
return files;
}
答案 0 :(得分:3)
您必须在3. + 2.5
.then
部分执行此操作
Promise.all()
答案 1 :(得分:2)
不,承诺是异步的,因此,不会按照您的想法运作。如果您想在承诺完成后执行某些操作,则必须将其放入承诺的then
回调中。以下是基于您的代码的示例:
uploadFilesOnServer(file) {
let files=[];
let file_id='';
const promise = getImageUrl()
.then((imageUrlResponse) => {
const data = new FormData();
data.append('file-0', file);
const { upload_url } = JSON.parse(imageUrlResponse);
console.log(upload_url);
return updateProfileImage(upload_url, data);
})
.then ((updateImageResponse) => {
file_id= JSON.parse(updateImageResponse);
console.log(file_id);
files.push(file_id);
console.log(files);
return files;
});
return promise;
}
let filesPromise = Promise.resolve([]);
if(this.state.files_to_upload.length > 0) {
const promises = this.state.files_to_upload.map((file) => {
return this.uploadFilesOnServer(file);
});
filesPromise = Promise.all(promises).then((results) => {
console.log(results);
return [].concat(...results);
});
}
// This is the final console.log of you (console.log(uploadedFilesURL);)
filesPromise.then((filesUrl) => console.log(filesUrl));
一本关于ES6的一本好书,特别是Promises,这本书Understanding ECMAScript 6 - Nicholas C. Zakas
编辑:
以下是示例代码的简单说明:
uploadFilesOnServer是一个接收文件,上传文件并在将来以承诺的形式完成上传时返回文件URL的函数。承诺在获取网址时会调用then
回调。
通过使用map函数,我们创建了一个url promises列表,我们从列表中每个文件执行uploadFilesOnServer
得到的结果。
Promise.all
方法等待列表中的所有promise完成,加入url结果列表并创建一个带有url列表结果的promise。我们需要这个,因为无法保证所有承诺会立即完成,我们需要在一次回调中收集所有结果以方便起见。
我们从then
回调中获取了网址。
答案 2 :(得分:0)
这是异步代码的工作方式。如果在异步调用从服务器获取文件后同步调用console.log(filesURL);
,则uploadFilesOnServer
无法正常工作。
关于您的代码,有几个问题:
1. uploadFilesOnServer(file)
{
let files=[];
let file_id='';
const image=file;
return getImageUrl().then((response) => {
const data = new FormData();
data.append('file-0', image);
const {upload_url} = JSON.parse(response);
console.log(upload_url);
updateProfileImage(upload_url, data).then ((response2) => {
const data2 = JSON.parse(response2);
file_id=data2;
console.log(file_id);
files.push(file_id);
console.log(files);
return files;
});
});
}
必须返回Promise,因为它是异步的。因此:
Promise.all
2.在您的主要功能正文中,您可以仅在其handler
中评估Microsoft.AnalysisServices.Tabular
执行的结果。
作为旁注,我建议您使用es7 async / await功能和一些像babel / typescript这样的转录器。这将大大减少编写例如同步代码的嵌套/复杂性。