API 调用上的 Node.js 循环

我正在尝试使用不同的参数进行少量 API 调用。获取数据并按天、城市最高温度、城市最低温度和有雨城市将其转换为 CSV 文件。


API 示例:https : //samples.openweathermap.org/data/2.5/forecast?q=M%C3%BCnchen,DE&appid=b6907d289e10d714a6e88b30761fae22


我有以下带有城市和 api 密钥的对象:


const cities = {

    0: ['Jerusalem', 'il'],

    1: ['New York', 'us'],

    2: ['Dubai', 'ae'],

    3: ['Lisbon', 'pt'],

    4: ['Oslo', 'no'],

    5: ['Paris', 'fr'],

    6: ['Berlin', 'de'],

    7: ['Athens', 'gr'],

    8: ['Seoul', 'kr'],

    9: ['Singapore', 'sgp'],

}


const apiKey = "[retracted]";

这是我想动态迭代的 API 调用,目前我只在第一个对象参数上运行它并最终将信息推送到天气,以便我可以操纵数据按天(前 5 天)对其进行排序,然后显示城市气温最高、气温最低的城市和所有下雨的城市:


request(`http://api.openweathermap.org/data/2.5/forecast?q=${cities[1][0]},${cities[1][1]}&mode=json&appid=${apiKey}`, (error, response, body) => {

    let data = JSON.parse(body);    

    let weather = {

        0: [day, highTemp, lowTemp, rain],

        1: [day, highTemp, lowTemp, rain],

        2: [day, highTemp, lowTemp, rain],

        3: [day, highTemp, lowTemp, rain],

        4: [day, highTemp, lowTemp, rain],

    }

    // day 1

    console.log(data['city']['name']);

    console.log(data['list'][0].dt_txt);

    console.log(data['list'][0].main['temp']);


    // day 2

    console.log(data['city']['name']);

    console.log(data['list'][8].dt_txt);

    console.log(data['list'][8].main['temp']);

    // day 3

    console.log(data['city']['name']);

    console.log(data['list'][16].dt_txt);

    console.log(data['list'][16].main['temp']);

    // day 4

    console.log(data['city']['name']);

    console.log(data['list'][24].dt_txt);

    console.log(data['list'][24].main['temp']);

    // day 5

    console.log(data['city']['name']);

    console.log(data['list'][32].dt_txt);

    console.log(data['list'][32].main['temp']);


});

我尝试使用带有对象中的键的 for 循环,但不幸的是它不显示数据,错误原因未定义。


哈士奇WWW
浏览 166回答 2
2回答

泛舟湖上清波郎朗

我建议使用 response-promise-native 来允许使用 async/await。这将允许我们遍历城市列表并将每个城市的天气数据附加到城市详细信息(名称和国家/地区)。一旦我们有了这些数据,我们就可以进行您提到的处理,我们可以获得最高和最低温度(请注意,温度以开尔文为单位,因此我们将转换为摄氏度。)重要的是要指出我按本地日期分组,如果您希望按UTC 日期分组,那么您应该更改该行:let timeOffset = entry.dt + result.weatherResponse.city.timezone;到let timeOffset = entry.dt;这是解释数据的一种稍微不同的方式!我现在已更新为按日期分组,结果如下所示:按当地日期分组:Date,Highest Temperature,Lowest Temperature,Cities With Rain2019-11-01,Dubai,Oslo,"Paris,Berlin"2019-11-02,Singapore,Oslo,"Lisbon,Paris,Berlin,Singapore"2019-11-03,Singapore,Oslo,"Lisbon,Paris,Berlin,Athens,Singapore"2019-11-04,Singapore,Oslo,"Lisbon,Paris,Berlin,Athens"2019-11-05,Singapore,Oslo,"Lisbon,Paris,Berlin,Singapore"2019-11-06,Singapore,Oslo,"Paris,Berlin,Singapore"2019-11-07,Seoul,Seoul,""按 UTC 日期分组:Date,Highest Temperature,Lowest Temperature,Cities With Rain2019-11-01,Dubai,Oslo,"Paris,Berlin"2019-11-02,Singapore,Oslo,"Lisbon,Paris,Berlin,Singapore"2019-11-03,Singapore,Oslo,"Lisbon,Paris,Berlin,Athens,Singapore"2019-11-04,Singapore,Oslo,"Lisbon,Paris,Berlin,Athens"2019-11-05,Singapore,Oslo,"Lisbon,Paris,Berlin,Singapore"2019-11-06,Singapore,Oslo,"Paris,Berlin,Singapore"代码:const rp = require("request-promise-native");const cities = {    0: ['Jerusalem', 'il'],    1: ['New York', 'us'],    2: ['Dubai', 'ae'],    3: ['Lisbon', 'pt'],    4: ['Oslo', 'no'],    5: ['Paris', 'fr'],    6: ['Berlin', 'de'],    7: ['Athens', 'gr'],    8: ['Seoul', 'kr'],    9: ['Singapore', 'sgp'],}async function getWeatherForCities() {    let results = [];    for (let [city, countryCode] of Object.values(cities)) {        console.log(`Getting weather for city: ${city}, country: ${countryCode}...`);        let weatherResponse = await rp({ url: `http://api.openweathermap.org/data/2.5/forecast?q=${city},${countryCode}&mode=json&appid=${apiKey}`, json: true});        results.push ({ city, countryCode, list: weatherResponse.list, weatherResponse });    }    let summary = results.map(res => {          return { city: res.city, countryCode: res.countryCode,        maxTemperature: getMaxTemperatureCelsius(res.list),        minTemperature: getMinTemperatureCelsius(res.list),        totalRainfall: getTotalRainFall(res.list)    }});    console.log("Summary (over forecasting interval): ", summary);    console.log("Result with the highest temperature: ", [...summary].sort((resA, resB) => resB.maxTemperature - resA.maxTemperature)[0]);    console.log("Result with the lowest temperature: ", [...summary].sort((resA, resB) => resA.minTemperature - resB.minTemperature)[0]);    console.log("Cities with rain: ", summary.filter(res => res.totalRainfall).map(res => res.city));    // Group by date (local) and city    let resultsGroupedByDateAndCity = {};    results.forEach(result => {        result.list.forEach(entry => {            let timeOffset = entry.dt + result.weatherResponse.city.timezone;            let date = new Date(timeOffset * 1000);            date.setHours(0,0,0,0);            let dateKey = date.toISOString().substring(0,10);            if (!resultsGroupedByDateAndCity[dateKey]) resultsGroupedByDateAndCity[dateKey] = {};            if (!resultsGroupedByDateAndCity[dateKey][result.city]) resultsGroupedByDateAndCity[dateKey][result.city] = [];            resultsGroupedByDateAndCity[dateKey][result.city].push(entry);        });    });    // Run through the keys.    let csvLines = ["Date,Highest Temperature,Lowest Temperature,Cities With Rain"];    for (let [date, obj] of Object.entries(resultsGroupedByDateAndCity)) {        let dailySummary = Object.entries(obj).map(([city, dayList]) => {              return { city,            maxTemperature: getMaxTemperatureCelsius(dayList),            minTemperature: getMinTemperatureCelsius(dayList),            totalRainfall: getTotalRainFall(dayList)        }});        console.log("Details for date " + date + ": ");        let resultWithHighestTemperature = [...dailySummary].sort((resA, resB) => resB.maxTemperature - resA.maxTemperature)[0];        let resultWithLowestTemperature = [...dailySummary].sort((resA, resB) => resA.minTemperature - resB.minTemperature)[0];        let citiesWithRain = dailySummary.filter(res => res.totalRainfall).map(res => res.city);        console.log("Result with the highest temperature: ", resultWithHighestTemperature);        console.log("Result with the lowest temperature: ", resultWithLowestTemperature);        console.log("Cities with rain: ", citiesWithRain);        csvLines.push([date, resultWithHighestTemperature.city, resultWithLowestTemperature.city, '"' + citiesWithRain.join(",") + '"'].join(","));    }    console.log("CSV result:\n", csvLines.join("\n"));}function KelvinToCelsius(kelvin) {    return (kelvin - 273.15);}// Return the max temperature for the forecastfunction getMaxTemperatureCelsius(responseList) {    // Get a list of the max temperatures for the forecast.    const maxTemps = responseList.map(entry => Number(entry.main.temp_max));    return KelvinToCelsius(Math.max(...maxTemps));}// Return the min temperature for the forecastfunction getMinTemperatureCelsius(responseList) {    // Get a list of the min temperatures for the forecast.    const minTemps = responseList.map(entry => Number(entry.main.temp_min));    return KelvinToCelsius(Math.min(...minTemps));}// Return the total rainfall for the forecastfunction getTotalRainFall(responseList) {    // Get a list of the min temperatures for the forecast.    const rain = responseList.map(entry => { return entry.rain ? Number(entry.rain["3h"]): 0 });    return rain.reduce((sum, val) => sum + val, 0)}getWeatherForCities();

慕姐4208626

您可以使用它Promise.all来实现这一点。Promise.all 返回一个单一的 Promise,当作为可迭代对象传递的所有承诺都已解决或可迭代对象不包含任何承诺时,该 Promise 会解决。const getData = (url) => {   return fetch(url)    .then(data => data.json())    .then(jsonData => jsonData)    .catch(err => {      console.log("Error while resolving the promise for url", url);            });  }let arr = [1, 2, 4, 5, 6, 7];const cities = {    0: ['Jerusalem', 'il'],    1: ['New York', 'us'],    2: ['Dubai', 'ae'],    3: ['Lisbon', 'pt'],    4: ['Oslo', 'no'],    5: ['Paris', 'fr'],    6: ['Berlin', 'de'],    7: ['Athens', 'gr'],    8: ['Seoul', 'kr'],    9: ['Singapore', 'sgp'],}const apiKey = "[retracted]";Promise.all(Object.keys(cities).map(id => {    let url = `http://api.openweathermap.org/data/2.5/forecast?q=${cities[id][0]},${cities[id][1]}&mode=json&appid=${apiKey}`;  return getData(url);  })) .then(results => {        // results is an array that contains the result of each api call        // so you can perform the action that you need here..        results.map(result => {          console.log(result['city']['name']);        });  })  .catch(err => {        // Handle the error..        console.log(err);  });  
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript