2 回答
TA贡献1818条经验 获得超3个赞
我建议使用 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 Rain
2019-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 Rain
2019-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 forecast
function 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 forecast
function 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 forecast
function 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();
TA贡献1852条经验 获得超7个赞
您可以使用它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);
});
添加回答
举报