javascript - Javascript 字典键未在 axios 请求中更新
问题描述
我目前在我的应用程序中有以下代码:
import {getTestData,getUserData} from "./js/apiInteractorModule.js";
const TEST_NAMES = ['CM10'];
var testData = {};
function populateTestData(){
return axios({
method: 'post',
url: '/get-session-cookie'
}).then(response => { //Get decrypted session data
getUserData(response.data.uuid,response.data.id_token).then(response => { //Get user data w/ decrypted session data (TODO: Integrate w/ data)
for (let i = 0; i < TEST_NAMES.length; i++){
getTestData(TEST_NAMES[i]).then(response => {
testData[TEST_NAMES[i]] = [];
for (var key in response.json){ //Creates {NAME: [{x: time, y: value}]} TODO: Adjust w/ user data
testData[TEST_NAMES[i]].push({
x: response.json[key].time,
y: response.json[key].value
});
}
});
}
})
return response;
}).catch(error => {
console.log(error);
return error;
});
}
getUserData 和 getTestData 与我的外部 API 交互的地方。getTestData 端点返回类似
{success: True/False, json: {String key: {time: UNIX time, value: float}}}
运行此之后,我希望 testData 看起来像
{CM10: [{x: time, y: value}]} API 调用中收到的每个值和时间。
跑步时
populateTestData().then(response => {
console.log(testData);
});
但是,console.log 打印出来的不是预期的字典
console.log(testData[CM10])
也打印 undefined,并且 testData.values 也是空的。
只是为了对比,当我在函数之外初始化 testData /
var testData = {"CM10": 10}
然后运行相同的代码,输出为
和运行console.log(testData["CM10"])"
打印10
为什么会这样,我能做些什么来解决它?
解决方案
不要依赖console.log ....
当您调用 populateTestData 时,它会返回值响应,即 {}(不确定 {} 如何/为什么在控制台中显示。)
同时,进行了两次 api 调用。现在响应在后台填充了值。因此,它会在您展开时显示为好像存在数据。但实际上数据是在 .then 被调用之后填充的。当您折叠它时,它会显示 {},最初收到的响应
确认
populateTestData().then(response => {
setTimeout(() => { // 5 seconds is a dummy value. You calculate the value and make sure all api calls are completed by that time
console.log(testData); // you might not see empty curly braces, without expanding
}, 5000);
});
这是控制台非常常见的棘手问题。你需要应用 promise 来避免这些。
我也看到你正在运行一个循环。Javascript是异步代码。所以 for 循环继续执行,不等待结果。在这种情况下,您将使用异步功能
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await
无法使用有效值重现您的代码,但下面的链接将对您有所帮助。
注意:如果你没有 for 循环,getTestData,或者你可以模拟你可以用 promise 确认 axios 响应
return getUserData(response.data.uuid,response.data.id_token).then(response => { //Get user data w/ decrypted session data (TODO: Integrate w/ data)
// for (let i = 0; i < TEST_NAMES.length; i++){
return getTestData(TEST_NAMES[0]).then(response => {
testData[TEST_NAMES[0]] = [];
for (var key in response.json){ //Creates {NAME: [{x: time, y: value}]} TODO: Adjust w/ user data
testData[TEST_NAMES[i]].push({
x: response.json[key].time,
y: response.json[key].value
});
}
return testData
});
// }