【问题标题】:NodeJS no data returned from functionNodeJS没有从函数返回数据
【发布时间】:2020-01-30 04:46:36
【问题描述】:

我正在开发一个简单的天气应用程序,它使用只有城市名称的 mysql 数据库。然后我在数据库中查询所有名称,然后向 openweathermap 的 API 发送天气信息请求。

function getCities() {
  con.connect();
  con.query(('SELECT city_name FROM cities'), (err, res) => {
    console.log(res);
    getWeather(cities);
  });
};

async function getWeather(cities) {
  var data = [];
  for (var i = 0; i < cities.length; i++) {
    var url = `http://api.openweathermap.org/data/2.5/weather?q=${cities[i].city_name}&units=metric&appid=271d1234d3f497eed5b1d80a07b3fcd1`;
    await request(url, (err, res, body) => {
      var json = JSON.parse(body);
      var weather = {
        city: json.name,
        temperature: json.main.temp,
        description: json.weather[0].description,
        icon: json.weather[0].icon
      };
      data.push(weather);
    });
  }
  console.log(data);
}

getCities() 函数按预期工作并返回所有城市,但错误发生在 getWeather 函数中,特别是这些错误:

Desktop/WeatherApp/node_modules/request-promise-core/lib/plumbing.js:130
            throw thrownException;
            ^

TypeError: Cannot read property 'temp' of undefined
    at Request.request [as _rp_callbackOrig] (/home/kristijan/Desktop/WeatherApp/app.js:60:41)
    at Request.plumbing.callback (/home/kristijan/Desktop/WeatherApp/node_modules/request-promise-core/lib/plumbing.js:76:39)
    at Request.RP$callback [as _callback] (/home/kristijan/Desktop/WeatherApp/node_modules/request-promise-core/lib/plumbing.js:46:31)
    at Request.self.callback (/home/kristijan/Desktop/WeatherApp/node_modules/request/request.js:185:22)
    at Request.emit (events.js:182:13)
    at Request.<anonymous> (/home/kristijan/Desktop/WeatherApp/node_modules/request/request.js:1161:10)
    at Request.emit (events.js:182:13)
    at IncomingMessage.<anonymous> (/home/kristijan/Desktop/WeatherApp/node_modules/request/request.js:1083:12)
    at Object.onceWrapper (events.js:273:13)
    at IncomingMessage.emit (events.js:187:15)
    at endReadableNT (_stream_readable.js:1094:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)

据我了解,它是在从 API 获取结果之前跳过箭头函数的内部?

【问题讨论】:

  • request 不返回承诺,因此您的 await 什么也不做。你需要实际使用 Promise。
  • 修复了它的一部分,现在它实际上返回了数据。现在我唯一无法得出结论的是,当我渲染页面时,我如何先等待数据返回然后再渲染它
  • 请正确缩进您的代码(您可以使用“编辑”链接修复它)。错误缩进的代码很难阅读。
  • 您可能不想在每次有人调用 getCities() 时都连接,因为如果这实际上是在创建与您的 MySQL 实例的连接,那是一个非常昂贵的调用,有时可能会失败——最好是在本地上下文中将连接保持为单例或仅作为成员变量

标签: javascript mysql node.js api


【解决方案1】:

await 仅在您等待的函数结果返回一个 Promise 时才等待异步操作。 request() 函数不返回承诺(它与您传递的回调一起使用),因此 await 不等待该结果。您可以改用 request-promise 库,它会返回一个承诺并且您不会向它传递回调。

这是一个例子:

const rp = require('request-promise');

async function getWeather(cities) {
  let data = [];
  for (let i = 0; i < cities.length; i++) {
    let url = `http://api.openweathermap.org/data/2.5/weather?q=${cities[i].city_name}&units=metric&appid=271d1234d3f497eed5b1d80a07b3fcd1`;
    let body = await rp(url);
    let json = JSON.parse(body);
    let weather = {
        city: json.name,
        temperature: json.main.temp,
        description: json.weather[0].description,
        icon: json.weather[0].icon
    };
    data.push(weather);
  }
  console.log(data);
}

注意,您也可以让请求 API 自动为您解析 JSON:

const rp = require('request-promise');

async function getWeather(cities) {
  let data = [];
  for (let i = 0; i < cities.length; i++) {
    let url = `http://api.openweathermap.org/data/2.5/weather?q=${cities[i].city_name}&units=metric&appid=271d1234d3f497eed5b1d80a07b3fcd1`;
    let json = await rp({uri:url, json: true});
    let weather = {
        city: json.name,
        temperature: json.main.temp,
        description: json.weather[0].description,
        icon: json.weather[0].icon
    };
    data.push(weather);
  }
  console.log(data);
}

2020 年 1 月编辑 - request() 模块处于维护模式

仅供参考,request 模块及其衍生模块(如 request-promise)现在处于维护模式,不会积极开发以添加新功能。您可以阅读更多关于推理的信息herethis table 中有一个备选方案列表,其中对每个备选方案进行了一些讨论。我自己一直在使用got(),它从一开始就是使用 Promise 构建的,而且使用简单。

【讨论】:

    猜你喜欢
    • 2015-04-21
    • 2020-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多