Promises解决方案的问题不明确



我正在实现一个选择和下载多个文档的功能。

首先,我构建了一个对象数组,其中包含每个选定文档的名称和指向其位置的链接。

getAllSelectedUrls = () => {
const { selectedFiles } = this.state;
const urls = [];
selectedFiles.forEach((file) => {
this.returnFileUrl(file.id).then(res => res.json()).then((data) => {
urls.push({ fileName: file.name, url: data.content_path });
});
});
return urls;
}

returnFileUrl()是一个异步API调用,用于通过ID:获取文件的链接

returnFileUrl = async (fileId) => {
try {
const resp = await fetch(`/file?fileId=${fileId}`);
return resp;
} catch (err) {
console.log(err);
}
}

我认为通过更新.then方法中的urls数组,我可以确保每个url在返回时都得到解析。

当我调用getAllSelectedUrls()时,我可以在控制台中记录阵列,并填充所有数据。然而,我无法对其进行迭代或通过索引访问任何对象,可能是因为此时数据尚未解析。

使用Promise.all((

getAllSelectedUrls = () => {
const { selectedFiles } = this.state;
return Promise.all(selectedFiles.map(file => {
return this.returnFileUrl(file.id)
.then(res => res.json())
.then(data => ({ fileName: file.name, url: data.content_path }))
}))
.then(urls => {
//do whatever you need to do with the urls array
})
.catch(e => console.log(e))
}

同意@Bergi的意见,return不会等到异步调用完成。它立即返回一个空数组。但是,如果urls数组已完全填充,则可以对每个解析进行检查。如果是,请将变量存储在某个位置,例如使用setState

或者只需将urls数组移动到该状态,并通过每次解析将url简单地推到该状态。

selectedFiles.forEach((file) => {
this.returnFileUrl(file.id).then(res => res.json()).then((data) => {
urls.push({ fileName: file.name, url: data.content_path });
if (urls.length === selectedFiles.length) {
this.setState({ urls });
}
});
});

试试这个:

(已编辑(

getAllSelectedUrls = async () => {
const { selectedFiles } = this.state;
const urls = [];
for (let i = 0; i < selectedFiles.length; i++) {
const file = selectedFiles[i];
res = await this.returnFileUrl(file.id);
data = await res.json();
urls.push({ fileName: file.name, url: data.content_path });
}
return urls;
}

像这样,该函数将在所有承诺都得到解决并推送url 后返回

最新更新