简体   繁体   English

NodeJS 函数没有返回数据

[英]NodeJS no data returned from function

I am working on a simple weather application which uses mysql database that has just the names of the cities.我正在开发一个简单的天气应用程序,它使用仅包含城市名称的 mysql 数据库。 Than i query the database for all the names and i send request to openweathermap's API for the weather info.然后我在数据库中查询所有名称,然后向 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);
}

The getCities() function works as expected and returns all the cities but the errors happen in the getWeather function particulary these errors: 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)

As far as i understood it is jumping the inside of the arrow function before getting the result from the API?据我所知,它是在从 API 获取结果之前跳转到箭头函数的内部?

await only waits for the async operation if the function result you are awaiting returns a promise.如果您正在等待的函数结果返回一个承诺, await只会等待异步操作。 The request() function does not return a promise (it works with the callback you are passing it) and thus await does not wait for that result. request()函数不返回承诺(它与您传递给它的回调一起工作)因此await不会等待该结果。 You can use the request-promise library instead which does return a promise and you do not pass it a callback.您可以改用request-promise库,它会返回一个 promise 并且您不会将回调传递给它。

Here's an example:这是一个例子:

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);
}

Note, you can also let the request API parse the JSON for you automatically:请注意,您还可以让请求 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);
}

EDIT Jan, 2020 - request() module in maintenance mode编辑 2020 年 1 月 - request() 模块处于维护模式

FYI, the request module and its derivatives like request-promise are now in maintenance mode and will not be actively developed to add new features.仅供参考, request模块及其衍生产品(如request-promise )现在处于维护模式,不会积极开发以添加新功能。 You can read more about the reasoninghere .您可以在此处阅读有关推理的更多信息。 There is a list of alternatives in this table with some discussion of each one. 此表中有一个备选方案列表,并对每个备选方案进行了一些讨论。 I have been using got() myself and it's built from the beginning to use promises and is simple to use.我自己一直在使用got()并且它从一开始就使用 promises 构建并且易于使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM