如何使用多个函数对提取的结果求和?

How to sum the results of a fetch using multiple functions?

我正在使用 OpenWeatherMapAPI 计算前 5 天的降水量总和。为此,我有 5 个异步函数,使用提取 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]

异步功能总是returns一个承诺。

你可以做的是使用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

您可以使用 await 来获取 async 函数的结果。

var rainTotals = await getData1() + await getData2() + await getData3() + await getData4() + await getData5();

这里发生了几件事。首先,回答你的问题,因为你的 getDataX 函数被声明为异步的,所以它们 return Promise 最终会解决或拒绝你正在寻找的实际值。

使用 Promises 时,您需要在所有这些 promises 已解决后对总值求和。

其次,您的代码中有一些重复。您会注意到 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)
})

异步函数延迟,因为它等待 await。 'return' 立即给出数据,这就是为什么数据给出空对象(当 console.log(getData1()) 只返回空对象时)。因此,应该等待获得总数据。 'total' 每个 getData 函数中的数据被推送到一个数组中。每个 getData 函数都在 asyncAll 函数中等待以立即记录数组。

// 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();