我正在使用axios向我的Nodejs后端发出Post请求,以使用AWS S3来为我需要的特定数据拉出Urls(与问题并不完全相关,但与上下文有关)。
在后端,我有一个包含12个条目的数组,每个元素都初始化为“测试”。然后,根据前端的json更新数组中的特定元素。更新一个这样的元素后,我立即console.log整个数组,它正确地具有更新的数组。当我在后端返回之前最后一次控制台控制台整个阵列时,所有条目都是“测试”,但我知道这可能是因为console.log不同步。但是,当我将该数组返回给frontend和console.log时,该数组仍然是所有12个“测试”,这使我相信'then'块在Post请求完成之前就已经执行了(这令人困惑) 。我不确定该怎么做,因为在前端进行其他数据验证之前,我需要正确的数组。任何建议将不胜感激。
我尝试过将发布请求放在一个单独的函数中并返回那个诺言,但这也不起作用。
handleSubmit(event) {
event.preventDefault();
//other code before
let json=JSON.stringify(data);
let post_data={json_data:json}
this.grabData(post_data)
.then((response) => {
console.log(response)
var myObj = JSON.parse(response.data.json_data);
console.log(myObj.length)
var i;
//Should output that certain elements have been changed, but all show up as 'test' still
for (i = 0; i < 12; i++) {
console.log("element " + i + " is: " + myObj[i])
}
this.state.urls = myObj;
var z;
for (z = 0; z < 12; z++) {
if (this.state.urls[z] === "test") {
this.state.urls.splice(z, 1);
z = z - 1;
}
}
//The state.urls should not be empty after the splicing, but it is because all elements are still 'test'
console.log("After splicing: " + this.state.urls)
});
}
grabData(post_data) {
return axios.post('/getCharts', post_data)
}
在后端:
app.post('/getCharts', (req, res) => {
var obj = JSON.parse(req.body.json_data)
let getThese = req.body[0]
var urls = ["test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test"];
var i;
var year = new Date().getFullYear();
console.log(year)
let jan = ''
let feb = ''
let mar = ''
let apr = ''
let may = ''
let jun = ''
let jul = ''
let aug = ''
let sep = ''
let oct = ''
let nov = ''
let dec = ''
for (i = 0; i < obj.length; i++) {
if (obj[i] == 1) {
key = 'charts/pieChart' + year + '-01-01.png'
console.log(key)
var params = {Bucket: bucketName, Key: key}
s3.headObject(params, function (err, metadata) {
if (!err) {
urls[0] = s3.getSignedUrl('getObject', params);
}
});
}
if (obj[i] == 2) {
key = 'charts/pieChart' + year + '-02-01.png'
console.log(key)
var params = {Bucket: bucketName, Key: key}
s3.headObject(params, function (err, metadata) {
if (!err) {
urls[1] = s3.getSignedUrl('getObject', params);
}
});
}
if (obj[i] == 3) {
key = 'charts/pieChart' + year + '-03-01.png'
console.log(key)
var params = {Bucket: bucketName, Key: key}
s3.headObject(params, function (err, metadata) {
if (!err) {
urls[2] = s3.getSignedUrl('getObject', params);
//This outputs a correctly updated array
console.log(urls)
}
});
}
//This if block is repeated 12 times, up to obj[i] = 12, so removing for sake of simplicity
}
var i2;
//This array prints out 12 'test' but I understand it's because console.log is executed async
for (i2 = 0; i2 < 12; i2++) {
console.log("urls" + i2 + " is: " + urls[i2])
}
let json=JSON.stringify(urls);
let post_data={json_data:json}
res.setHeader('Content-Type', 'application/json');
res.send(post_data);
});
答案 0 :(得分:0)
我的朋友,Obj for循环是讨厌的代码,哈哈。for循环的原因是只做一次。我清理了您的代码。它应该工作。但是,如果不是这样,这就是基本思想。
app.post('/getCharts', (req, res) => {
var obj = JSON.parse(req.body.json_data)
let getThese = req.body[0]
var urls = ["test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test"];
var i;
var year = new Date().getFullYear();
console.log(year)
let jan = ''
let feb = ''
let mar = ''
let apr = ''
let may = ''
let jun = ''
let jul = ''
let aug = ''
let sep = ''
let oct = ''
let nov = ''
let dec = ''
let uploads = 0;
const finishedUpload = () => {
uploads++;
if (uploads === obj.length) {
var i2;
//This array prints out 12 'test' but I understand it's because console.log is executed async
for (i2 = 0; i2 < 12; i2++) {
console.log("urls" + i2 + " is: " + urls[i2])
}
let json=JSON.stringify(urls);
let post_data={json_data:json}
res.setHeader('Content-Type', 'application/json');
res.send(post_data);
}
}
for (i = 0; i < obj.length; i++) {
const myKey = i+1;
if (obj[i] == myKey) {
key = 'charts/pieChart' + year + '-0' + myKey +'-0' + myKey +'.png'
console.log(key)
var params = {Bucket: bucketName, Key: key}
s3.headObject(params, function (err, metadata) {
if (!err) {
urls[i] = s3.getSignedUrl('getObject', params);
finishedUpload()
}
});
}
}
});