【发布时间】:2019-11-26 17:19:13
【问题描述】:
我正在使用 axios 向我的 Nodejs 后端发出 Post 请求,以使用 AWS S3 为我需要的特定数据提取 Urls(与问题不完全相关,但与上下文相关)。
在后端,我有一个包含 12 个条目的数组,初始化为每个元素的“测试”。然后我根据前端的 json 更新数组中的特定元素。在我更新一个这样的元素后,我立即 console.log 整个数组并且它正确地具有更新的数组。当我在返回后端之前最后一次 console.log 整个数组时,所有条目都是“测试”,但我知道这可能是因为 console.log 不是同步的。但是,当我将该数组返回到前端并 console.log 响应时,该数组仍然是全部 12 个“测试”,这让我相信在 Post 请求甚至完成之前执行“then”块(这令人困惑) .我不确定该怎么做,因为在前端进行其他数据验证之前我需要正确的数组。任何建议将不胜感激。
我尝试将发布请求放在单独的函数中并返回该承诺,但这也不起作用。
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);
});
【问题讨论】:
-
很难理解你在问什么。也许在代码中添加一些您期望的内容。但是在您的
grabData(post_data)请求中。你永远不会返回任何东西。如果您想将数据返回给客户端,您需要在grabData末尾发送return this.state.urls。 -
感谢您的回复。我最初拥有它,所以它会执行 axios.post(...).then((response) => ...) 但我被告知尝试将发布请求放在单独的函数中并返回该承诺。所以,grabData 中的 return axios.post('/getCharts', post_data) 是为了返回我想的承诺。
-
您能否包含您的
/getCharts函数。该函数似乎没有返回您期望的结果。 -
刚刚编辑了 OP!
-
您对服务器不只是返回一堆“测试”有多大信心?我很有信心。
标签: node.js reactjs asynchronous callback axios