☆☆ 新着記事 ☆☆

2020年5月28日木曜日

複数のfetch関数を使って、複数のプロミスを取得する - Promise.all()



Promise.all takes an array of promises (it technically can be any iterable, but is usually an array) and returns a new promise.


let promise = Promise.all([...promises...]);

下記の例では、fetchesのアレイが全て満たされるまで、.then()以下の処理は待機している。


function getMultipleURLs() {

  let array = new Array;
  var fetches = [];

  for (let i = 49; i <51; i++)
    fetches.push(
      fetch("https://coronavirus-tracker-api.herokuapp.com/v2/locations/"+i)
      .then(res => {return res.json(); })
      .then(function(data){

            array.push(data.location.timelines.confirmed.timeline);
            console.log(data.location.timelines.confirmed.timeline); //Output1:
          }
      )
      .catch(status, err => {return console.log(status, err);})
    );
  }
  Promise.all(fetches).then(function() {
    console.log (Object.keys(array[0]).length);
  });
  }


#Output1
{2020-01-22T00:00:00Z: 1, 2020-01-23T00:00:00Z: 9, 2020-01-24T00:00:00Z: 15, 2020-01-25T00:00:00Z: 39, 2020-01-26T00:00:00Z: 60, …}
{2020-01-22T00:00:00Z: 14, 2020-01-23T00:00:00Z: 22, 2020-01-24T00:00:00Z: 36, 2020-01-25T00:00:00Z: 41, 2020-01-26T00:00:00Z: 68, …}
#Output2
127

(参考)

Promise API

https://javascript.info/promise-api

How to use fetch within a for-loop, wait for results and then console.log it


**実際にコードを使ってみた。
他の国は、国別に感染者数、死亡者数がまとまっているけど、中国だけは省ごとに複数のAPIがあるので、全部Fetchして、取得したValueを合算しなければいけなかった、という県です。


function getCN() {
  let array = new Array;
  let array_death = new Array;
  let update = new Array;
  var fetches = [];
  for (let i = 49; i <82; i++) {
    fetches.push(
      fetch("https://coronavirus-tracker-api.herokuapp.com/v2/locations/"+i)
      .then(res => {return res.json(); })
      .then(function(data){ 
            array.push(data.location.timelines.confirmed.timeline);
array_death.push(data.location.timelines.deaths.timeline);
update = data.location.last_updated;
          })
      .catch(status, err => {return console.log(status, err);})
    );
  }//fetchのfor Loopの終り
 
  Promise.all(fetches).then(function() {
  //////////New Patients///////////////
all_values=[]
for( let i=0; i< Object.keys(array).length; i++){
all_values.push(Object.values(array[i]))
}

var latest_patients_sum = 0
var yesterday_patients_sum = 0
var two_days_ago_patients_sum =0
var seven_days_ago_patients_sum=0
var two_weeks_ago_patients_sum=0
for(let i =0; i < all_values.length; i++){
//Today's patients sum
latest_len = all_values[i].length-1
latest_patients_sum +=  parseInt(all_values[i][latest_len])
//yesterday's patients sum
yesterday_patients_sum +=  parseInt(all_values[i][latest_len-1])
//Two days ago's patients sum
two_days_ago_patients_sum +=  parseInt(all_values[i][latest_len-2])
//seven_days_ago's patients sum
seven_days_ago_patients_sum +=  parseInt(all_values[i][latest_len-7])
//two_weeks_ago's patients sum
two_weeks_ago_patients_sum +=  parseInt(all_values[i][latest_len-14])
};

document.getElementById('countryName').innerHTML = "China";
let population = 1392730000;
document.getElementById('population').innerHTML = population.toLocaleString('en');

document.getElementById('update').innerHTML = update.substr(0, 10);

document.getElementById('cases').innerHTML = latest_patients_sum.toLocaleString('en');
document.getElementById('cases_per100KCapita').innerHTML = ((Number(latest_patients_sum)/Number(population))*100000).toLocaleString('en',{minimumFractionDigits: 2, maximumFractionDigits: 2});

let today_new_patients =latest_patients_sum - yesterday_patients_sum;
document.getElementById('new_patients').innerHTML = today_new_patients.toLocaleString('en');

let yesterday_new_patients = yesterday_patients_sum - two_days_ago_patients_sum;
document.getElementById('yesterday_new_patients').innerHTML =yesterday_new_patients.toLocaleString('en');
let oneWeek_new_patients = latest_patients_sum - seven_days_ago_patients_sum;
document.getElementById('oneWeek_new_patients').innerHTML =oneWeek_new_patients.toLocaleString('en');
let twoWeeks_new_patients = seven_days_ago_patients_sum - two_weeks_ago_patients_sum;
document.getElementById('twoWeeks_new_patients').innerHTML =twoWeeks_new_patients.toLocaleString('en');

  //////////New deaths///////////////
all_values_death=[]
for( let i=0; i< Object.keys(array_death).length; i++){
all_values_death.push(Object.values(array_death[i]))
}

var latest_deaths_sum = 0
var yesterday_deaths_sum = 0
var two_days_ago_deaths_sum =0
var seven_days_ago_deaths_sum=0
var two_weeks_ago_deaths_sum=0
for(let i =0; i < all_values_death.length; i++){
//Today's deaths sum
latest_len = all_values_death[i].length-1
latest_deaths_sum +=  parseInt(all_values_death[i][latest_len])
//yesterday's deaths sum
yesterday_deaths_sum +=  parseInt(all_values_death[i][latest_len-1])
//Two days ago's deaths sum
two_days_ago_deaths_sum +=  parseInt(all_values_death[i][latest_len-2])
//seven_days_ago's deaths sum
seven_days_ago_deaths_sum +=  parseInt(all_values_death[i][latest_len-7])
//two_weeks_ago's deaths sum
two_weeks_ago_deaths_sum +=  parseInt(all_values_death[i][latest_len-14])
};

document.getElementById('deaths').innerHTML = latest_deaths_sum.toLocaleString('en');
document.getElementById('deaths_per100KCapita').innerHTML = ((Number(latest_deaths_sum)/Number(population))*100000).toLocaleString('en',{minimumFractionDigits: 2, maximumFractionDigits: 2});

let today_new_deaths =latest_deaths_sum - yesterday_deaths_sum;
document.getElementById('new_deaths').innerHTML = today_new_deaths.toLocaleString('en');
console.log(today_new_deaths)
let yesterday_new_deaths = yesterday_deaths_sum - two_days_ago_deaths_sum;
document.getElementById('yesterday_new_deaths').innerHTML =yesterday_new_deaths.toLocaleString('en');
let oneWeek_new_deaths = latest_deaths_sum - seven_days_ago_deaths_sum;
document.getElementById('oneWeek_new_deaths').innerHTML =oneWeek_new_deaths.toLocaleString('en');
let twoWeeks_new_deaths = seven_days_ago_deaths_sum - two_weeks_ago_deaths_sum;
document.getElementById('twoWeeks_new_deaths').innerHTML =twoWeeks_new_deaths.toLocaleString('en');

document.getElementById('percent').innerHTML = ((latest_deaths_sum/latest_patients_sum)*100).toLocaleString("en", {minimumFractionDigits: 2, maximumFractionDigits: 2}) + "%";

  }); //Promise.allのfunctionと.thenの終り

  }


**メモ 最初に作成:Promise.all()を使わないと、順番が守られないのでダメだったコード

num_patientsをfor loopを実行した後で、
 console.log("Loop外の書き込みたい"+num_patients)
  document.getElementById("countryCode").innerHTML = num_patients;
を実行したいが、実際にはfor loopの前に実行されて 0 が返る。

for (var i =49 ; i<= 50; i++){
alert(i)
var num_patients = []
url = 'https://coronavirus-tracker-api.herokuapp.com/v2/locations/'+i
fetch(url)
.then(function(resp) { return resp.json() })
.then(function(data) {
///Get Timeline Length
let latest_timeline_len = Object.keys(data.location.timelines.confirmed.timeline).length;
alert("長さ"+latest_timeline_len)
///New Patients Object
let latest_patients = data.location.timelines.confirmed.timeline
/// List of Patients Object Value
let list_num_patients = []
for( var item in  latest_patients ) {
list_num_patients.push(latest_patients[item]);
}
let confirmedCases =  list_num_patients[latest_timeline_len-1];

num_patients.push(confirmedCases)
console.log(i+ "回目:" + num_patients)

}) // 1つのfetchを処理する2つめの .then()の終了
 .catch(status, err => {return console.log(status, err);})
}// getCNの fetch()を繰り返す回数の End of For Loop
 console.log("Loop外の書き込みたい"+num_patients)
  document.getElementById("countryCode").innerHTML = num_patients;
  });

0 件のコメント:

コメントを投稿