javascript - 如何使用 fetch() 用来自服务器的数据填充变量?

标签 javascript asynchronous 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通过调用函数 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 才会真正填充该属性。

我的想法对吗? 如何在正确的迭代中填充属性?

最佳答案

您的问题是您没有等待数据到达并将其发布到服务器。您可以重构 getWeatherDatagenerate 来实现这一点。

第一件事是从 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/

相关文章:

javascript - 单击标题时如何获取列名称/索引

javascript - 在名字和姓氏之后对数组进行排序,javascript

javascript - 是否可以在加载 jQuery 之前预先注册处理程序?

mysql - 在 Perl 中使用 selectrow_array 获取 2 个值

javascript - Electron-dl 无法读取未定义的属性 'then'

javascript - 如何在数据表的下一个/上一个分页按钮上捕获事件

android - 异步更新 Android 上下文菜单

c# - 通过 IPC 传递任务<T>

PHP 在上传图像时从 React Native 接收空数据?

git fetch 只获取当前分支