我有一个函数,可以从 Open Weather API 获取数据,并将一些值分配给某些 HTML 元素的 innerText 属性。这部分工作正常。
但我还需要将这些值之一 (data["main"]["temp"]
) 存储到对象的属性 (userData.temp
)。
//Function to get data from Open Weather
const getWeatherData = () => {
let zipInputValue = document.getElementById("zip").value;
const weatherUrl = `http://api.openweathermap.org/data/2.5/weather?zip=${zipInputValue},${weatherCountryCode}&units=metric&appid=`;
fetch(weatherUrl + weatherApiKey).then((res) => {
if (res.status != 200) {
console.log("Looks like there's been a problem.");
return;
}
res.json().then((data) => {
descriptionElement.innerText = "Weather: " + data["weather"][0]["description"];
currenttempElement.innerText = "Temperature:" + data["main"]["temp"] + " °C";
userData.temp = data["main"]["temp"];
mintempElement.innerText = "Min.:" + data["main"]["temp_min"] + " °C";
maxtempElement.innerText = "Max.:" + data["main"]["temp_max"] + " °C";
});
});
console.log(userData.temp);
};
在我的代码末尾,有一个由点击事件触发的函数generate()
,它调用getWeatherData()
,然后发布userData通过调用函数
发送到服务器。postProjectData(userData)
将 .temp
/*---------- Post Data to the Server ---------- */
const postProjectData = async (userData) => {
const rawResponse = await fetch("http://localhost:8080/addData", {
method: "POST",
body: JSON.stringify(userData),
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
});
const response = await rawResponse.json();
return response;
};
/*---------- Generate Entry ---------- */
const btn = document.getElementById("generate");
btn.addEventListener("click", generate);
function generate() {
getWeatherData();
console.log("test");
userData.date = newDate;
userData.userResponse = getUserResponse();
postProjectData(userData);
getProjectData();
}
但是,当第一次调用此单击事件时,该属性对于服务器来说将变为空。第二次,它与前一次迭代的值一致。这意味着,它也落后了一次迭代。
我假设这是因为当浏览器访问 getWeatherData()
内的 fetch
时,由于它是一个异步函数,它会转到 postProjectData (用户数据)
;只有在那之后,fetch
才会真正填充该属性。
我的想法对吗? 如何在正确的迭代中填充属性?
最佳答案
您的问题是您没有等待数据到达并将其发布到服务器。您可以重构 getWeatherData
和 generate
来实现这一点。
第一件事是从 getWeatherData
返回一个 Promise,这样你就可以等待数据被获取:
const getWeatherData = () => new Promise((resolve, reject) => {
let zipInputValue = document.getElementById("zip").value;
const weatherUrl = `http://api.openweathermap.org/data/2.5/weather?zip=${zipInputValue},${weatherCountryCode}&units=metric&appid=`;
fetch(weatherUrl + weatherApiKey).then((res) => {
if (res.status != 200) {
console.log("Looks like there's been a problem.");
return reject();
}
res.json().then((data) => {
descriptionElement.innerText = "Weather: " + data["weather"][0]["description"];
currenttempElement.innerText = "Temperature:" + data["main"]["temp"] + " °C";
userData.temp = data["main"]["temp"];
mintempElement.innerText = "Min.:" + data["main"]["temp_min"] + " °C";
maxtempElement.innerText = "Max.:" + data["main"]["temp_max"] + " °C";
resolve();
});
});
console.log(userData.temp);
});
这里的要点是解析/拒绝 Promise,让函数调用者(在本例中为 generate
)获取数据。
然后我们重构生成
:
async function generate() {
await getWeatherData();
console.log("test");
userData.date = newDate;
userData.userResponse = getUserResponse();
postProjectData(userData);
getProjectData();
}
这个想法是将 generate
转换为异步函数,使其等待数据到达 (getWeatherData
) 以便调用 postProjectData
.
关于javascript - 如何使用 fetch() 用来自服务器的数据填充变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61386514/