异步函数太早完成传递变量

时间:2018-03-13 21:26:21

标签: javascript async-await

所以我想从另一个文件中要求这个函数并在main.js中使用它。但我一直在undefined。现在这并不让我感到惊讶。因为使用console.log,我看到prepareWeather()getWeather()完成之前已完成。但它也保持空白/未定义。

该函数需要在main.js中每15分钟更新一次变量globalWeather。所以它更新了最新的天气信息。 我用async / await和.next()尝试了一切,但我不知道我在做什么了。我感到非常迷茫。

我将代码剥离到只有使其可读的必要条件。这也是我希望getWeather()位于单独文件中的原因。这很长。

有人可以告诉我如何使这项工作?而且,请解释一下为什么这不起作用?

main.js

const getWeather = require("./functions/getweather.js");
let globalWeather = {};

prepareWeather();
async function prepareWeather() {
  console.log(`a: ${Date.now()}`);
  globalWeather = await getWeather(); //return object
  console.log(`b: ${Date.now()}`);
  console.log(globalWeather);
  console.log(`c ${Date.now()}`);
  setTimeout(prepareWeather, 10000); //900000 when it works
}

getweather.js

module.exports = exports = async function getWeather(){

  const request = require("request");
  const key = `XXX`;
  const lat = `10.01`;
  const lon = `10.01`;
  const units = `metric`;

  let url = `http://api.openweathermap.org/data/2.5/weather`+
            `?APPID=`+key+
            `&lat=`+lat+
            `&lon=`+lon+
            `&units=`+units;

  console.log(`1 ${Date.now()}`);
  await request({
    url: url,
    json: true
  }, await function (error, response, body) {

    console.log(`2 ${Date.now()}`);

    if (!error && response.statusCode === 200) {

      console.log(`3 ${Date.now()}`);

      let wobj = body;
      let id = wobj.weather[0].id;

      if (id === 200 || id === 201) {
        wobj.emoji = `⛈`;
      } else if(id === 300) {
        wobj.emoji = ``; 
      }

      console.log(`4 ${Date.now()}`)

      //console.log(wobj);
      return wobj;
      }
  });
}

控制台:

a: 1520974253102
1 1520974253103
b: 1520974253125
undefined //This is console.log(globalWeather);
c 1520974253125
2 1520974253159
3 1520974253159
4 1520974253159
getweather.js中的

//console.log(wobj);最终会在我的控制台中返回一个对象。但不是在main.js。

1 个答案:

答案 0 :(得分:0)

所以我在这里分享我的解决方案,如果其他方面也遇到同样的问题。评论中提供的link Barmar解释说它非常好。

所以在main.js:

//Global var  
let globalWeather = {};

//Calling the function at startup 
getWeather(function(result) {
  globalWeather = result;
})}, 10000

//Call the function after 15 minutes 
// and every 15 minutes after that
setInterval(function() {
  getWeather(function(result) {
    globalWeather = result;
  })}, 900000
);

在getweather.js:

//Pretty much the same only start with:
module.exports = exports = function getWeather(callback){

//And instead of return wobj:
callback(wobj);