快速解释一下这个代码块:我有一个files
对象,它是我上传的所有文件,然后我还有一个signedUrls
对象,它包含来自之前S3函数的所有带签名的URL。这些对象具有匹配的索引。
第一个axios.put
上载文件,第二个axios.post
将文件密钥保存到我的数据库。(除非上传成功,否则我不想将其保存到我的数据库中,因此axios.post
在回调中的位置。)
文件上传得很好,但是fileId
没有正确循环,通常会反复保存相同的fileId
。也就是说,如果我上传了五个文件,它们会上传到S3,但它们在我的数据库中都有相同的id。知道为什么会发生这种情况吗?
fileIds = {"1": "someFileId", "2": "someOtherId" }
for (let i = 0; i < files.length; i++) {
axios.put(signedUrls[i], files[i], config).then(res => {
axios.post('https://myapi.com/add-file', {
fileId: fileIds[i]
}).then(res => {
// success
});
发布于 2017-12-27 23:41:29
这是因为您正在同步for
循环中进行异步调用。
在调用post
请求时,您的循环已经完成。
你可以使用Promise.all
来解决这个问题:
const promises = files.map((file, i) => {
// create a new promise with correct index, but don't call it yet
return new Promise((resolve, reject) => {
return axios.put(signedUrls[i], file, config)
.then(res => {
return axios.post('https://myapi.com/add-file', {
fileId: fileIds[i]
}).then(res => {
resolve(res)
// todo: also handle errors here
})
})
})
})
// actually invoke your calls here
Promise.all(promises).then(res => /* success */ )
本质上,您要做的是同步创建promise调用(但还没有实际调用它们),以便可以使用正确的索引,然后使用Promise.all
实际调用promise数组。
发布于 2017-12-28 00:07:08
问题是i
绑定到您的.post
部分中的相同值。
要解决这个问题,你可以使用一个自执行的匿名函数。
如下所示:
for (let i = 0; i < files.length; i++) {
(function(i) {
axios.put(signedUrls[i], files[i], config).then(res => {
axios.post('https://myapi.com/add-file', {
fileId: fileIds[i]
}).then(res => {
// success
});
})(i);
}
https://stackoverflow.com/questions/47999546
复制相似问题