javascript - 如何使用 fetch() 使用来自服务器的数据填充变量?
问题描述
我有一个从 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.temp
通过调用该函数将其发布到服务器postProjectData(userData)
。
/*---------- 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();
}
但是,当第一次调用此单击事件时,该属性对服务器变为空。第二次,它与前一次迭代的值一致。意思是,它也是落后的一个迭代。
我假设这是因为当浏览器进入fetch
内部getWeatherData()
时,因为它是一个异步函数,它会继续postProjectData(userData)
;只有在那之后,才fetch
实际填充属性。
我想对了吗?以及如何在正确的迭代中填充属性?
解决方案
您的问题是您没有等待数据到达以将其发布到服务器。你可以重构getWeatherData
并generate
做到这一点。
第一件事是返回一个 Promise ,getWeatherData
这样你就可以等待数据被获取:
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
)获取数据。
然后我们重构generate
:
async function generate() {
await getWeatherData();
console.log("test");
userData.date = newDate;
userData.userResponse = getUserResponse();
postProjectData(userData);
getProjectData();
}
这个想法是转换generate
成一个异步函数,让它等待数据到达( getWeatherData
),以便调用postProjectData
.
推荐阅读
- javascript - 尝试使用 selenium 进行刮擦自动化,但网站可以检测到 selenium
- docker - Read-the-Docs Local Instance:Docs构建成功但找不到错误(404)
- r - 为什么线性回归中的 R^2 受 ggplot2 中 x 轴的比例影响
- notepad++ - Notepad ++在两行之间添加空格
- python - 替换列表中的元素 - 使用包含所述元素的嵌套列表(python3)
- javascript - 如何将小数四舍五入到最接近的 0.5(0.5、1.5、2.5、3.5)
- protocol-buffers - protobuf 是 grpc 中唯一使用的技术吗?
- python-3.x - 框架关闭 Tkinter 的问题
- r - 在终端中运行 R .ipynb 脚本
- javascript - 将事件侦听器添加到 javascript 文件