这个块的快速解释:我有一个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
});
答案 0 :(得分:1)
这是因为你在同步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
用于node = [['1001', '2008-01-06T02:12:13Z', ['']],
['1002', '2008-01-06T02:13:55Z', ['']],
['1003', '2008-01-06T02:13:00Z', ['Lion', 'Rhinoceros', 'Leopard', 'Panda']],
['1004', '2008-01-06T02:15:20Z', ['Lion', 'Leopard', 'Eagle', 'Panda', 'Tiger']],
['1005', '2008-01-06T02:15:48Z', ['Lion', 'Panda', 'Cheetah', 'Goat', 'Tiger']],
['1006', '2008-01-06T02:13:30Z', ['']],
['1007', '2008-01-06T02:13:38Z', ['Cheetah', 'Tiger', 'Goat']]]
实际上调用了承诺数组。
答案 1 :(得分:-1)
问题是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);
}
绑定了相同的值
要解决此问题 - 您可以使用自行执行的匿名功能
像这样:
000
001
011
010
110
111
101
100