Javascript 如何在Resact js ES6中使用Promise.all
我想做的是上传文件到服务器上,然后得到上传文件的URL并预览它。文件可以是多个。为此,我编写了以下代码:Javascript 如何在Resact js ES6中使用Promise.all,javascript,ajax,reactjs,Javascript,Ajax,Reactjs,我想做的是上传文件到服务器上,然后得到上传文件的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(thi
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);
您必须在
上执行此操作。然后承诺的一部分。all()
这就是异步代码的工作方式。您不能期望您的console.log(fileurl)如果在从服务器获取文件的异步调用之后同步调用它,则代码>将正常工作
关于您的代码,有几个问题:
1.uploadFilesOnServer
必须返回承诺,因为它是异步的。因此:
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;
});
});
}
2.在您的主要功能主体内,您可以评估承诺的结果。所有执行仅在其各自的then处理程序中进行
作为补充说明,我建议您将es7/功能与一些诸如babel/typescript之类的Transpiler一起使用。这将大大减少编写此类异步代码的嵌套/复杂度。不,promise是异步的,因此不能按您认为的方式工作。如果希望在承诺完成后执行某项操作,则必须将其放入承诺的回调中,然后将其放入回调中。以下是基于您的代码的示例:
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的好书
编辑:
下面是示例代码的简单解释:
UploadFileOnServer是一个函数,它接收文件,上载文件,并在将来完成上载时以承诺的形式返回文件URL。promise将调用其,然后在获取url时调用回调
通过使用map函数,我们创建了一个url承诺列表,即对列表中的每个文件执行uploadFilesOnServer
得到的结果
Promise.all
方法等待列表中的所有承诺完成,加入url结果列表,并使用结果(url列表)创建承诺。我们需要这样做,因为不能保证所有的承诺都能一次完成,为了方便起见,我们需要在一次回调中收集所有结果
我们从然后回调中获取URL
您需要更多地了解Javascript中的承诺。首先,console.log(uploadedFilesURL)代码>将立即执行。解析承诺后需要运行的代码进入.then()
回调。其次,Promise.all()
接受一个promises数组作为参数,同时传递一个包含文件id
类型的数组。Thank alot@Tr1et可能重复。您给定的代码片段解决了这个问题。我在上面的理解是,首先我们将“files\u to\u upload”数组映射到“file”并将其传递到“uploadFileOnServer”。此函数返回包含“文件”数组的承诺。然后在每个promise上调用promise.all并将所有数据连接到一个数组中。现在“filePromise”将拥有所有组合数据,并且可以访问filePromise的整个“.then()”。请告诉我,如果我得到了正确的或纠正我在哪里得到了错误。谢谢我在答案中添加了一个解释,因为它有点长。有什么你们不明白的吗?现在,我想知道哪些文件无法上传到服务器上。这就是承诺失败的原因。我该怎么做?
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;
});
});
}
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));