데이터가 추가될 때 웹에 관리자 모드 부분을 만들어 관리자가 데이터가 추가됨에 따라 기존 코드를 고치지 않게 하기
날짜 적용하기 로 기존에 했던 것을 적용해보기로 했다.
기존에 연관된
Set_data.js , Daily_Increase_Day.js, Daily_Total,Increase_Modify2.js, Pi_Chart_Bar_Chart.js
코드를 수정해야했다.
let start = '2020-03-03'
let end = '2020-12-31'
function requestApiAndGetData() {
return fetch('https://coronaproject.herokuapp.com/api/covidDate').then(res => res.json()).then(obj => {
return obj.data
})
}
function calculateDateArray(end){
let sdt = new Date(start); // 2020년 03월 04일 부터 시작
let edt = new Date(end);
let dateDiff = Math.ceil((edt.getTime()-sdt.getTime())/(1000*3600*24));
let Year,Month,Day; // 각 날짜별 날짜 생성
const date_array = []; // 해당 필요부분 넣을 배열 생성
for(let i=0;i<dateDiff;i++) // 2020년 3월 4일부터 마지막 데이터 csv까지의 날짜의 차이에서 +1 한 값이 150 (ex 현재는 7월 31일까지)
{
sdt.setDate(sdt.getDate()+1) // 3월 4일 계산 후 하루씩 증가
Year = sdt.getFullYear().toString().slice(2,4); // 2020년이 아닌 뒤의 두자리 수만 필요하므로 slice 사용
Month = (sdt.getMonth()+1).toString().length==1 ? '0'+ (sdt.getMonth()+1).toString() :(sdt.getMonth()+1).toString() ; // 한자리 수 인경우 앞에 0을 붙인다.
Day = sdt.getDate().toString().length==1? '0'+sdt.getDate().toString() : sdt.getDate().toString();
date_array.push(Year+Month+Day); //합친 내용을 배열로 만들어 준다.
}
return date_array; //해당 배열을 반환한다.
}
async function Set_Date(){
let data = await requestApiAndGetData();
let date_array = await calculateDateArray(data);
return date_array;
}
export {Set_Date}
주요 부분은 2개의 함수를 async await을 통해 비동기에 순차성을 부여하였다. 해당 함수만 작동시키면
먼저requestApiAndGetData
를 수행하고 return한 data 변수를 가지고 다시calculateDateArray
에 매개변수로 넣어 수행하고date_array
를 반환한다.
return fetch(~).then().then({return ~})
import {url} from './utils/Data.js'
import {Set_Date} from "./utils/Set_Date.js";
const numberInput = document.getElementById('numberInput');
numberInput.addEventListener('keyup',(e)=>checkClick(e))
const checkClick = function(e){
if(e.key === 'Enter' && Number.isInteger(Number(numberInput.value)))
{
load(numberInput.value);
}
}
async function load (value) {
const get_date = [];
const get_sum = [];
try {
const datas = await Promise.all(Set_Date().map(date =>
dfd.read_csv(`${url}${date}.csv`)
));
datas.forEach(data => {
get_sum.push(data.body__items__item__incDec.data[data.body__items__item__incDec.data.length - 1]);
get_date.push(data.body__items__item__createDt.data[0].slice(2, 10));
})
let newSum = [];
let newDate = [];
get_sum.forEach((sum, index) => {
if (sum > value) {
newSum.push(sum);
newDate.push(get_date[index]);
}
})
const dataFrame = {'sum': newSum, 'data': newDate};
const df = new dfd.DataFrame(dataFrame);
df.plot('table').table();
}
catch(err){
alert(err);
}
}
async await에서
Promise.all
을 이용하였다.
import {url} from './utils/Data.js'
import {Set_Date} from "./utils/Set_Date.js";
const numberInput = document.getElementById('numberInput');
numberInput.addEventListener('keyup',(e)=>checkClick(e))
const checkClick = function(e){
if(e.key === 'Enter' && Number.isInteger(Number(numberInput.value)))
{
load(numberInput.value);
}
}
async function load (value) {
const get_date = [];
const get_sum = [];
try {
const datas = await Set_Date()
.then(values=>values.map(date => dfd.read_csv(`${url}${date}.csv`)))
.then(data=>Promise.all(data));
datas.forEach(data => {
get_sum.push(data.body__items__item__incDec.data[data.body__items__item__incDec.data.length - 1]);
get_date.push(data.body__items__item__createDt.data[0].slice(2, 10));
})
let newSum = [];
let newDate = [];
get_sum.forEach((sum, index) => {
if (sum > value) {
newSum.push(sum);
newDate.push(get_date[index]);
}
})
const dataFrame = {'sum': newSum, 'data': newDate};
const df = new dfd.DataFrame(dataFrame);
df.plot('table').table();
}
catch(err){
alert(err);
}
}
async await은 같지만 해당
Set_Date
함수를 이용해
values
부분은 ["200304", "200305", "200306", "200307", "200308", "200309", "200310", "200311", "200312", "200313", "200314", "200315", "200316", "200317", "200318", "200319", "200320", "200321", "200322", "200323", "200324", "200325", "200326", "200327", "200328", "200329", "200330", "200331", "200401", "200402", "200403", "200404", "200405", "200406", "200407", "200408", "200409", "200410", "200411", "200412", "200413", "200414", "200415", "200416", "200417", "200418", "200419", "200420", "200421", "200422", "200423", "200424", "200425", "200426", "200427", "200428", "200429", "200430", "200501", "200502", "200503", "200504", "200505", "200506", "200507", "200508", "200509", "200510", "200511", "200512", "200513", "200514", "200515", "200516", "200517", "200518", "200519", "200520", "200521", "200522", "200523", "200524", "200525", "200526", "200527", "200528", "200529", "200530", "200531", "200601", "200602", "200603", "200604", "200605", "200606", "200607", "200608", "200609", "200610", "200611", …]
이러한 배열부분이고
해당 내용을 map함수를 이용해 각각 분리한 것이
date
이다.
data
부분은Promise
형태로 반환되어 이를 처리하기 위해Promise.all
을 사용하여 return 하였다.
Danfo 사이트에서도 해당 dfd.read_csv
부분을 Promise
형태로 반환되어 처리하기 때문에 그에대해 처리를 위해서는 Promise.all
을 이용하여 반환시켜야 원하는 값을 얻을 수 있다.
const datas = await Promise.all(Set_Date().map(date =>
dfd.read_csv(`${url}${date}.csv`)
));
const datas = await Set_Date()
.then(values=>values.map(date =>dfd.read_csv(`${url}${date}.csv`)))
.then(data=>Promise.all(data));
마찬가지로 유사하게 진행한다. 결국 다른점은 Promise를 처리하기 위해 진행된다.
const datas = await Set_Date()
.then(values=>values.map(date =>dfd.read_csv(`${url}${date}.csv`)))
.then(data=>Promise.all(data));
기존코드에서 end변수만을 이용한 것을 바꾸었다.
const datas = await Promise.all(Set_Date().map(date =>
dfd.read_csv(`${url}${date}.csv`)
));
const datas = await Set_Date()
.then(values=>values.map(date =>dfd.read_csv(`${url}${date}.csv`)))
.then(data=>Promise.all(data));
이렇게 바꿨었는데
const datas = await Promise.all(Set_Date()
.then(values=>values.map(date =>dfd.read_csv(`${url}${date}.csv`))))
이렇게 코드는 안되는 것인가 고민해보니 오류가 떴다.
TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
console.log(Set_Date())
결과
const datas = await Promise.all(Set_Date().map(date =>
dfd.read_csv(`${url}${date}.csv`)
));
배열형태로 리턴된다.
Set_Date().map(date => dfd.read_csv(${url}${date}.csv))
해당부분이 Promise로 반환하므로 이를 처리하려면Promise.all(Promise형태)
로 진행되어야한다.
const datas = await Set_Date()
.then(values=>values.map(date => dfd.read_csv(`${url}${date}.csv`)))
.then(data=>Promise.all(data));
Promise 형태로 리턴한다.
Promise이므로 then형태로 만들어 처리하되 Promise를 then으로 순차적으로 처리하기때문에 첫번째 then을 통해 처리된 data 부분이 Promise형태이기 때문에 이를 다시 then형태로 Promise.all을 이용한다.
- async await을 통해서 비동기의 순차적 처리가 가능하고
async 함수는 일반 함수와 다르게 return 값이 같은 Object에 같은 배열 형태로 나타나더라도 실체는Promise
형태이다.
일반함수는 그냥 Object에 같은 배열 형태이다.- 즉, 리턴한 값을 처리할 때
일반함수는 map함수를 쓰면서 이를 전체를 묶어 처리하는Promise.all(Promise 배열형태)
이고
async 함수는 then으로 연결처리를 해야하므로Promise형태.then(~).then(promise형태=>Promise.all(promise 배열형태))
로 처리한다.