如何使用多个函数对 fetch 的结果求和?
Posted
技术标签:
【中文标题】如何使用多个函数对 fetch 的结果求和?【英文标题】:How to sum the results of a fetch using multiple functions? 【发布时间】:2021-02-24 01:40:06 【问题描述】:我正在使用 OpenWeatherMapAPI 计算前 5 天的降水总量。为此,我有 5 个使用 fetch api 调用 api 的异步函数。收到的数据与我有关,是跨越 24 小时的每小时历史天气数据。 完整代码如下。 json 响应存储到一个常量 (Ex.const histData1
) 中,然后在给定的 24 小时内对其进行迭代以求和所有一个值。 注意:湿度被用作概念证明,因为这里已经有一段时间没有下雨了
for (var i in histData1.hourly)
total1 += histData1.hourly[i].humidity;
;
当我将结果值 total1 发送到控制台时,我会收到预期的结果。 当试图将所有这些结果加在一起时,我的麻烦就来了,即 total1 + total2 + total3 + total4 + total5。 我认为可能可行的一种解决方案是在每个函数处返回 total[1,2,3,4,5] 变量,然后将它们相加。例如。
var rainTotals = getData1() + getData2() + getData3() + getData4() + getData5()
console.log(rainTotals)
这导致了以下输出:[object Promise][object Promise][object Promise][object Promise][object Promise] 所以它似乎是一个数据类型问题。
任何人都可以阐明从五个单独的函数中添加所有 湿度 值。随意烘烤我的代码,我对此很陌生。
谢谢!
//WORKS Provies a json of hourly weather data for (1)24 hr period starting 5 days ago.
const fiveDaysAgo = Math.floor((Date.now() / 1000)-432000);
const fivedayURL = "http://api.openweathermap.org/data/2.5/onecall/timemachine?lat=29.8833&lon=-97.9414&dt=" + fiveDaysAgo +"&appid="
async function getData5()
const response5 = await fetch(fivedayURL)
const histData5 = await response5.json();
var total5 = 0
for (var i in histData5.hourly)
total5 += histData5.hourly[i].humidity;
;
console.log(total5);
return total5;
getData5();
const fourDaysAgo = Math.floor((Date.now() / 1000)-345600);
const fourdayURL = "http://api.openweathermap.org/data/2.5/onecall/timemachine?lat=29.8833&lon=-97.9414&dt=" + fourDaysAgo +"&appid=5ffab1cda2c6b2750c78515f41421805"
async function getData4()
const response4 = await fetch(fourdayURL)
const histData4 = await response4.json();
var total4 = 0;
for (var i in histData4.hourly)
total4 += histData4.hourly[i].humidity
;
console.log(total4);
return total4;
getData4();
const threeDaysAgo = Math.floor((Date.now() / 1000)-259200);
const threedayURL = "http://api.openweathermap.org/data/2.5/onecall/timemachine?lat=29.8833&lon=-97.9414&dt=" + threeDaysAgo +"&appid=5ffab1cda2c6b2750c78515f41421805"
async function getData3()
const response3 = await fetch(threedayURL);
const histData3 = await response3.json();
var total3 = 0;
for (var i in histData3.hourly)
total3 += histData3.hourly[i].humidity;
;
console.log(total3);
return total3;
getData3();
const twoDaysAgo = Math.floor((Date.now() / 1000)-172800);
const twodayURL = "http://api.openweathermap.org/data/2.5/onecall/timemachine?lat=29.8833&lon=-97.9414&dt=" + twoDaysAgo +"&appid=5ffab1cda2c6b2750c78515f41421805"
async function getData2()
const response2 = await fetch(twodayURL);
const histData2 = await response2.json();
var total2 = 0;
for (var i in histData2.hourly)
total2 += histData2.hourly[i].humidity;
;
console.log(total2);
return total2;
getData2();
const oneDaysAgo = Math.floor((Date.now() / 1000)-86400);
const onedayURL = "http://api.openweathermap.org/data/2.5/onecall/timemachine?lat=29.8833&lon=-97.9414&dt=" + oneDaysAgo +"&appid=5ffab1cda2c6b2750c78515f41421805"
async function getData1()
const response1 = await fetch(onedayURL);
const histData1 = await response1.json();
var total1 = 0;
for (var i in histData1.hourly)
total1 += histData1.hourly[i].humidity;
;
console.log(total1);
return total1;
getData1();
var rainTotals = getData1() + getData2() + getData3() + getData4() + getData5()
console.log(rainTotals)//returns [object Promise][object Promise][object Promise][object Promise][object Promise]
【问题讨论】:
developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 【参考方案1】:异步函数总是返回一个承诺。
您可以做的是使用 Promise.all 将它们聚合到一个数组中。
Promise.all([getData1(), getData2(), getData3(), getData4(), getData5()]).then((values) =>
var sum = 0;
for(var i=0; i<values.length; i++)
sum += values[i];
console.log(sum);
);
来源:Async Functions
【讨论】:
【参考方案2】:你可以使用await
得到async
函数的结果。
var rainTotals = await getData1() + await getData2() + await getData3() + await getData4() + await getData5();
【讨论】:
【参考方案3】:这里发生了几件事。首先,回答您的问题,因为您的 getDataX
函数被声明为异步的,它们返回的 Promise 最终将使用您正在寻找的实际值解决或拒绝。
在使用 Promises 时,您需要在所有这些 Promise 都解决后对总值进行求和。
其次,您的代码中有一些重复。您会注意到getDataX
函数的内部结构之间几乎没有区别。为了简化这一点,您可以将差异提取为函数参数,并将所有相同的代码封装在一个函数中。
这将导致如下实现:
function getDaysAgo(days)
return Math.floor((Date.now() / 1000) - (86400 * days))
async function getDataForDaysAgo(days)
let daysAgo = getDaysAgo(days)
const apiURL = `http://api.openweathermap.org/data/2.5/onecall/timemachine?lat=29.8833&lon=-97.9414&dt=$daysAgo&appid=5ffab1cda2c6b2750c78515f41421805`
const apiResponse = await fetch(apiURL)
const responseJson = await apiResponse.json()
var total = 0
responseJson.hourly.forEach(hour =>
total += hour.humidity
);
console.log(`getDataForDaysAgo($days) returns $total`)
return total
async function getDataSums()
var data1 = await getDataForDaysAgo(5)
var data2 = await getDataForDaysAgo(4)
var data3 = await getDataForDaysAgo(3)
var data4 = await getDataForDaysAgo(2)
var data5 = await getDataForDaysAgo(1)
return data1 + data2 + data3 + data4 + data5;
getDataSums().then(result =>
console.log(result)
)
【讨论】:
【参考方案4】:异步函数延迟,因为它等待等待。 'return' 立即给出数据,这就是为什么数据给出空对象(当 console.log(getData1()) 只返回空对象时)。所以应该等待获取总数据。每个 getData 函数中的“总”数据被推送到一个数组中。每个 getData 函数在 asyncAll 函数中获取 await 以一次记录数组。
// Data array
let arr = [];
//WORKS Provies a json of hourly weather data for (1)24 hr period starting 5 days ago.
const fiveDaysAgo = Math.floor((Date.now() / 1000)-432000);
const fivedayURL = "http://api.openweathermap.org/data/2.5/onecall/timemachine?lat=29.8833&lon=-97.9414&dt=" + fiveDaysAgo +"&appid=5ffab1cda2c6b2750c78515f41421805"
async function getData5()
const response5 = await fetch(fivedayURL)
const histData5 = await response5.json();
var total5 = 0
for (var i in histData5.hourly)
total5 += histData5.hourly[i].humidity;
;
console.log(total5);
await arr.push(total5);
return total5;
getData5();
const fourDaysAgo = Math.floor((Date.now() / 1000)-345600);
const fourdayURL = "http://api.openweathermap.org/data/2.5/onecall/timemachine?lat=29.8833&lon=-97.9414&dt=" + fourDaysAgo +"&appid=5ffab1cda2c6b2750c78515f41421805"
async function getData4()
const response4 = await fetch(fourdayURL)
const histData4 = await response4.json();
var total4 = 0;
for (var i in histData4.hourly)
total4 += histData4.hourly[i].humidity
;
console.log(total4);
await arr.push(total4);
return total4;
getData4();
const threeDaysAgo = Math.floor((Date.now() / 1000)-259200);
const threedayURL = "http://api.openweathermap.org/data/2.5/onecall/timemachine?lat=29.8833&lon=-97.9414&dt=" + threeDaysAgo +"&appid=5ffab1cda2c6b2750c78515f41421805"
async function getData3()
const response3 = await fetch(threedayURL);
const histData3 = await response3.json();
var total3 = 0;
for (var i in histData3.hourly)
total3 += histData3.hourly[i].humidity;
;
console.log(total3);
await arr.push(total3);
return total3;
getData3();
const twoDaysAgo = Math.floor((Date.now() / 1000)-172800);
const twodayURL = "http://api.openweathermap.org/data/2.5/onecall/timemachine?lat=29.8833&lon=-97.9414&dt=" + twoDaysAgo +"&appid=5ffab1cda2c6b2750c78515f41421805"
async function getData2()
const response2 = await fetch(twodayURL);
const histData2 = await response2.json();
var total2 = 0;
for (var i in histData2.hourly)
total2 += histData2.hourly[i].humidity;
;
console.log(total2);
await arr.push(total2);
return total2;
const oneDaysAgo = Math.floor((Date.now() / 1000)-86400);
const onedayURL = "http://api.openweathermap.org/data/2.5/onecall/timemachine?lat=29.8833&lon=-97.9414&dt=" + oneDaysAgo +"&appid=5ffab1cda2c6b2750c78515f41421805"
async function getData1()
const response1 = await fetch(onedayURL);
const histData1 = await response1.json();
var total1 = 0;
for (var i in histData1.hourly)
total1 += histData1.hourly[i].humidity;
;
console.log(total1);
//Push data after data asynced
await arr.push(total1);
return total1;
//Moved getData function to asyncAll function.
var rainTotals = [];
// Awaited for getData functions, logged total data.
async function asyncAll()
await getData1();
await getData2();
await getData3();
await getData4();
await getData5();
await console.log(arr.join(', '), 'async');
asyncAll();
【讨论】:
以上是关于如何使用多个函数对 fetch 的结果求和?的主要内容,如果未能解决你的问题,请参考以下文章
JS fetch API:如何使用一个异步函数从多个文件中获取内容?