首页 > 解决方案 > 返回的对象未定义

问题描述

我目前正在研究每 10 分钟从OpenWeatherMap 的 API获取数据的气象站。

每 10 秒通过MQTT在“本地/温度”主题中发布一次温度,以便其他系统(例如加热器或空调)可以根据温度执行进一步的操作。

每隔 10 分钟,在新数据检索的同时,也会通过 MQTT 发布天气操作。

每 10 秒发布一次数据是项目的要求,但对于这种情况并不重要。

我遇到的问题是:我对OWM API 的请求是在一个额外的文件中完成的,该文件包含一个应该将数据作为对象返回的函数。同时数据存储在一个文件中,以便在网络故障的情况下保存最后的本地状态并且仍然可以使用。

我已经写入文件,稍后将添加“离线阅读”功能。我还注意到该assembleURL()功能实际上是不必要的,但我还没有改变它。

我在 JavaScript / Nodejs 方面还比较新,但我已经有 Java 和 Python 的经验,所以可能是我错误地混合了 Java 的一些东西。

有人可以向我解释为什么我在openWeatherMapCall.js中返回的对象是未定义的吗?我感谢每一个提示。

我的文件weather-station.js调用openWeatherMapCall.jsgetData中的函数:

const mqtt = require('mqtt');
const owm = require('./lib/openWeatherMapCall');
const client = mqtt.connect('mqtt://localhost:1885');
const fs = require('fs');
const config = require('../config/config.json');
const owmConfig = config.owm;

let weatherData = owm.getData(owmConfig.city, owmConfig.owmapikey, owmConfig.lang, "metric");
console.log(weatherData); // -> it says undefined


setInterval(_ => {
    weatherData = owm.getData(owmConfig.city, owmConfig.owmapikey, owmConfig.lang, "metric");
    client.publish("local/condition", toString(weatherData.weatherID));
    console.log('successful publish of wID ' + weatherData.weatherID);
}, 600000); //10 min

setInterval(_ => {
    client.publish("local/temperature", toString(weatherData.celsius));
    console.log('successful publish of ' + weatherData.celsius + ' celsius');
    }, 30000); //10 sec

我的 OWM API 调用为openWeatherMapCall.js

const fetch = require('node-fetch');
const fs = require('fs');
const util = require("util");

function assembleURL (city, apiKey, lang, units){
    let url = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "&units=" + units + "&lang=" + lang + "&appid=" + apiKey;
    console.log("url: " + url);
    return url;
}
function getData(city, apiKey, lang, units){
let url = assembleURL(city, apiKey, lang, units )
    fetch(url)
        .then(function(resp) { return resp.json() }) // Convert data to json
        .then(function(data) {
            var currentWeather = {
                weather: data.weather[0].description,
                weatherID: data.weather[0].id,
                celsius: Math.round(parseFloat(data.main.temp)),
                wind: data.wind.speed,
                location: data.name
            };
            let toString = JSON.stringify(currentWeather);
            fs.writeFile('../config/weather.json', toString, err => {
                if (err) {
                    console.log('Error while writing', err)
                } else {
                    console.log('Successful write')
                }
            })
            return currentWeather;
        })
        .catch( err => {
            console.log('caught it!',err);

        });
}
module.exports = {getData};

标签: javascriptnode.js

解决方案


从返回fetch响应getData并使用thenonowm.getData作为 fetch 返回一个Promise.

function getData(city, apiKey, lang, units){
    let url = assembleURL(city, apiKey, lang, units )
    return fetch(url)....
}

owm.getData(owmConfig.city, owmConfig.owmapikey, owmConfig.lang, "metric").then((weatherData) => {
 console.log(weatherData)
});

推荐阅读