javascript - javascript/react - 带有 for 循环 POST 请求的异步/等待
问题描述
我正在创建一个图片转换器,其中我的 JS 代码从用户那里获取文件输入,将其发送到我的 python 后端,在那里它们被转换并保存到一个文件夹中。然后 Python 将响应发送回 JS (react),后者将每个文件的状态单独更新为“已转换”并重新渲染必要的组件。
我有一个 for 循环,它为每个文件发送单独的 POST 请求。这很好,直到我想在转换所有文件后为整个目录创建一个 .zip。我的问题就在那里。我的 zip 总是返回空文件或文件不完整。
// function which takes the file inputs from user
uploadBatch = async () => {
const files = this.getFilesFromInput();
const batch = Math.floor(Math.random() * 999999 + 100000);
for (let i = 0; i < files.length; i++) {
// sets the state which will then be updated
await this.setState(
{
files: [
...this.state.files,
{
// file state values
}
]
},
() => {
const formData = new FormData();
// appends stuff to form data to send to python
axios
.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
responsetype: 'json'
})
.then(response => {
// update the state for this particular file
});
}
);
}
return batch;
};
// function which zips the folder after files are converted
handleUpload = async e => {
e.preventDefault();
// shouldn't this next line wait for uploadBatch() to finish before
// proceeding?
const batch = await this.uploadBatch();
// this successfully zips my files, but it seems to run too soon
axios.post('/api/zip', { batch: batch }).then(response => {
console.log(response.data);
});
};
我使用过异步/等待,但我认为我没有很好地使用它们。我不太从根本上理解这个概念,因此将不胜感激。
解决方案
每当您调用setState()
时,组件都会重新渲染。理想情况下,您应该完成所有操作并setState()
在最后调用。
这样的事情应该让事情为你工作
// function which takes the file inputs from user
uploadBatch = async () => {
const files = this.getFilesFromInput();
const batch = Math.floor(Math.random() * 999999 + 100000);
const files = [];
for (let i = 0; i < files.length; i++) {
const formData = new FormData();
// appends stuff to form data to send to python
const res =
await axios
.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
responsetype: 'json'
});
files.push('push data into files arr');
}
return { files, batch };
};
// function which zips the folder after files are converted
handleUpload = async e => {
e.preventDefault();
// get batch and files to be uploaded and updated
const { files, batch } = await this.uploadBatch();
// this successfully zips my files, but it seems to run too soon
await axios.post('/api/zip', { batch: batch }).then(response => {
console.log(response.data);
});
// set the state after all actions are done
this.setState( { files: files });
};
推荐阅读
- php - 我如何 chroot php-fpm (7.3) 以与 Apache 2.4.10 一起使用?
- javascript - 在 JavaScript 中首先使用 for 循环加载最后一条记录
- nativescript - Nativescript-dev-appium 测试在“检查模拟器是否正在运行”之后卡住了
- ios - 位置发生显着变化后,应用程序不会在后台静默启动
- groovy - 嵌套闭包中的 Groovy resolveStrategy
- reactjs - 我可以在循环中更改单个子组件而不重新渲染整个列表(反应钩子)
- c++ - C ++中的两个连续for循环,第二个循环不起作用
- ios - 无法使用 segue swift 5 将数据从一个控制器传递到另一个控制器
- python-3.x - 使用 Python 在(子)文件夹中搜索特定文件名
- c# - 在 Visual Studio 中设置表视图时出现公共列表错误