티스토리 뷰
async awit에 대한 이해가 모자른 상황
async function getTrafficInformationArrowDataLocal() {
let jsonResult = [];
let lcList = [25, 26, 29, 103, 104, 105, 106, 231, 233, 356, 358, 379, 382, 410, 380, 414];
try {
for (let i = 0; i < lcList.length; i++) {
const query = `
SELECT
TO_CHAR(SLVC.AREA_CREDATE, 'YYYY-MM-DD HH24:MI:SS') AS CREDATE,
SLVC.INT_LCNO,
SMI.INT_FLOWNUMBER,
SUM((SLVC.AREA_T1_VOL + SLVC.AREA_T2_VOL + SLVC.AREA_T3_VOL + SLVC.AREA_T4_VOL)) AS VOL,
ROUND(AVG(SLVC.AREA_QUEUE), 1) AS AQUEUE,
ROUND(AVG(SLVC.AREA_ASPD), 1) AS ASPEED
FROM
SCS_L_VC_CHLTRAFFIC SLVC, SCS_M_VC_CHL SMVC, SCS_M_INTPHASE SMI
WHERE
SLVC.CHL_NO = SMVC.CHL_NO
AND SLVC.INT_LCNO = SMVC.INT_LCNO
AND SMVC.INT_LCNO = SMI.INT_LCNO
AND SMVC.AREA_RING = SMI.INT_RING
AND SMVC.AREA_PHASENO = SMI.INT_PHASENO
AND TO_CHAR(SLVC.AREA_CREDATE, 'YYYYMMDDHH24MISS') =
(
SELECT
TO_CHAR(MAX(AREA_CREDATE), 'YYYYMMDDHH24MISS')
FROM
SCS_L_VC_CHLTRAFFIC
WHERE
INT_LCNO = ${lcList[i]}
)
AND SLVC.INT_LCNO = ${lcList[i]}
GROUP BY SLVC.AREA_CREDATE, SLVC.INT_LCNO, SMI.INT_FLOWNUMBER
`;
const bindParams = [];
const result = await Connection.a_sendQuery(query, bindParams);
if (Connection.isEmpty(result)) {
return Connection.createJsonResponse(false, Constants.MESSAGE_FAILED, jsonResult);
} else {
for (let i = 0; i < result.rows.length; i++) {
jsonResult.push({
lcNo: result.rows[i].INT_LCNO,
flowNum: result.rows[i].INT_FLOWNUMBER,
speed: Math.round(result.rows[i].ASPEED * 100) / 100,
vol: Math.round(result.rows[i].VOL * 100) / 100,
queue: Math.round(result.rows[i].AQUEUE * 100) / 100,
linkId: result.rows[i].INT_LCNO + "0" + result.rows[i].INT_FLOWNUMBER,
});
}
}
}
console.log(jsonResult);
return Connection.createJsonResponse(true, Constants.MESSAGE_SUCCESS, jsonResult);
} catch (e) {
console.log(" ---- E: getTrafficInformationArrowData ----");
console.error(e);
console.log(" ---- E: getTrafficInformationArrowData ----");
}
}
교차로 10개의 데이터를 적용하였지만 지도에서 너무 늦게 뜨는 상황이 발생이되었다. 그래서 이걸 줄이기 위해서 친구에게 물어보았다 어떻게하면 데이터를 빠르게 가져올 수 있을까라고? 그랬더니 받은 답은?
친구 : 답을 말해주자면 일단 api호출에 5초이상이걸린다 프론트는 api호출이 끝날때까지 기다렸다 데이터를 뿌려주기때문이다.
그렇다 프론트는 api호출을 끝날때까지 기다렸다가 데이터를 지도위에 뿌려주는것이다. 그렇다면 동기인가? 아니다. 비동기가 맞다 그럼 왜 그런지 좀 공부해보고자한다.
친구가 지적해준 사항은 이렇다.
1. 로직에 대한 이해
2. 비동기 동기에 대한 이해 부족
3. 쿼리의 문제점
그렇다면 내가할 수 있는 최선은 ? async awit 부터 공부해보고자한다.
프라미스 : 프로미스는 자바스크립트 비동기 처리에 사용되는 객체이다. 여기서 자바스크립트 비동기 처리란 '특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행하는 자바스크립트의 특성'을 의미한다.
프라미스의 3가지 상태 (states)프로미스를 사용할 때 알아야 하는 가장 기본적인 개념이 바로 프로미스의 상태이다.여기서 말하는 상태란? 프로미스의 처리 과정을 의미한다. new Promise()로 프로미스를 생성하고 종료될 때까지 3자기 상태를 갖습니다.1. Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태2. Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태3. Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
프로미스 처리 흐름 - 출처 : MDN
async이란?
- async는 함수 앞에 위치한다.
함수앞에 async를 붙이면 항상 프라미스를 반환합니다.
await 란?- await는 async 함수에서만 동작합니다.
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("완료!"), 1000)
});
let result = await promise; // 프라미스가 이행될 때까지 기다림 (*)
alert(result); // "완료!"
}
f();
예제를 보면 result 값에 await를 넣고 promise가 이행 되면 완료!가 나타난다그럼 위에서 언급한 오래걸리는 상황은 위에 코드인
async function getTrafficInformationArrowDataLocal() {
let jsonResult = [];
let lcList = [25, 26, 29, 103, 104, 105, 106, 231, 233, 356, 358, 379, 382, 410, 380, 414];
try {
for (let i = 0; i < lcList.length; i++) {
..........
`;
const bindParams = [];
const result = await Connection.a_sendQuery(query, bindParams);
위에 async에서 보낸 값이 프로미스가 이행 되었을때 await가 작동하기에 5초이상이 걸리는거다?라고 확인할 수 있었다그렇다면 내가 생각하는 문제는 쿼리로 불러오는 데이터가 5초이상 걸림에 따라 지도위에 뿌려지는 상황이 딜레이되는 것이었고 쿼리를 수정하지 않으면 안된다? 라고 판단이 되는 상황으로 보였다.
SELECT
TO_CHAR(SLVC.AREA_CREDATE, 'YYYY-MM-DD HH24:MI:SS') AS CREDATE,
SLVC.INT_LCNO,
SMI.INT_FLOWNUMBER,
SUM((SLVC.AREA_T1_VOL + SLVC.AREA_T2_VOL + SLVC.AREA_T3_VOL + SLVC.AREA_T4_VOL)) AS VOL,
ROUND(AVG(SLVC.AREA_QUEUE), 1) AS AQUEUE,
ROUND(AVG(SLVC.AREA_ASPD), 1) AS ASPEED
FROM
SCS_L_VC_CHLTRAFFIC SLVC, SCS_M_VC_CHL SMVC, SCS_M_INTPHASE SMI
WHERE
SLVC.CHL_NO = SMVC.CHL_NO
AND SLVC.INT_LCNO = SMVC.INT_LCNO
AND SMVC.INT_LCNO = SMI.INT_LCNO
AND SMVC.AREA_RING = SMI.INT_RING
AND SMVC.AREA_PHASENO = SMI.INT_PHASENO
AND TO_CHAR(SLVC.AREA_CREDATE, 'YYYYMMDDHH24MISS') =
(
SELECT
TO_CHAR(MAX(AREA_CREDATE), 'YYYYMMDDHH24MISS')
FROM
SCS_L_VC_CHLTRAFFIC
WHERE
INT_LCNO = ${lcList[i]}
)
AND SLVC.INT_LCNO = ${lcList[i]}
GROUP BY SLVC.AREA_CREDATE, SLVC.INT_LCNO, SMI.INT_FLOWNUMBER
동료가 짠 쿼리를 확인하고 불러오는 데이터를 확인해보았다.
{ lcNo: 382,
flowNum: 8,
speed: 34,
vol: 28,
queue: 22.7,
linkId: '38208' },
let lcList = [25, 26, 29, 103, 104, 105, 106, 231, 233, 356, 358, 379, 382, 410, 380, 414];
일단 lcNo에 아래 해당하는 교차로의 넘버들이 들어가는 것을 확인하였고 총 16개의 교차로가 출력됨을 확인하였고 색을 칠해주기 위해 speed 데이터를 가져왔고 그 처리를
getColor() {
return (d) => { //recieve the prop
let data = this.arrowData.find(el => el.linkId == d)
if (data === undefined) {
return "#fff"
} else {
switch(this.getCurrentMenuIndex) {
case 10:
case 11:
if (data.speed < 15) {
return "#EE6452"
} else if (data.speed >= 15 && data.speed < 25) {
return "#EEB952"
} else if (data.speed >= 25) {
return "#35B863"
}
break;
case 12:
case 13:
if (data.vol > 250) {
return "#EE6452"
} else if (data.vol > 150 && data.vol <= 250) {
return "#EEB952"
} else if (data.vol <= 150) {
return "#35B863"
}
break;
case 14:
case 15:
if (data.queue > 40) {
return "#EE6452"
} else if (data.queue > 25 && data.queue <= 40) {
return "#EEB952"
} else if (data.queue <= 25) {
return "#35B863"
}
break;
}
}
};
},
위 코드에서 진행하고있었다.
내가 원하는 화면은 무엇인가? 일단 초기 화면에서 화살표를 뿌리고 데이터가 들어오면 엎어서 불이들어오는 형식이 더 낫지않을까?
참고하고 공부한 페이지 ↓
'연습장 > 삽질의 흔적' 카테고리의 다른 글
삽질, 마무리 (0) | 2022.11.03 |
---|---|
삽질을 하다 예외처리를 공부하다. (0) | 2022.11.03 |
동기와 비동기? 언제까지 헷갈릴래? (0) | 2022.11.02 |
본격 삽질 일대기 자율주행 첫삽 (0) | 2022.10.27 |
setInterval() 함수를 알아보자 (0) | 2022.10.27 |