연습장/삽질의 흔적

async awit를 모르는 나... 멍청...이

찬찬잉 2022. 11. 15. 16:27

 

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;
          }
        }
      };
    },

위 코드에서 진행하고있었다. 

내가 원하는 화면은 무엇인가? 일단 초기 화면에서 화살표를 뿌리고 데이터가 들어오면 엎어서 불이들어오는 형식이 더 낫지않을까?

 

 

 

참고하고 공부한 페이지 ↓

 

async와 await

 

ko.javascript.info

 

프라미스

 

ko.javascript.info

 

자바스크립트 Promise 쉽게 이해하기

(중급) 자바스크립트 입문자를 위한 Promise 설명. 쉽게 알아보는 자바스크립트 Promise 개념, 사용법, 예제 코드. 예제로 알아보는 then(), catch() 활용법

joshua1988.github.io