ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Async / Await 주의해서 다루기
    Javascript 2020. 4. 25. 15:18

    async / await를 다룰 때 주의해야 할 점입니다.

     

    Non Blocking 형태의 I/O 작업을하는 Node.js는 익숙하지 않을 수 있습니다.

     

    let printNum = (number, delaySec) => {
        setTimeout(() => console.log(number), delaySec); // i/o 작업을 대신한다.
    };
    
    let logPrintNum = (number, delaySec) => {
        console.log(`Enter logPrintNum ${number}`);
        printNum(number, delaySec);
        console.log(`Exit  logPrintNum ${number}`);
    };
    
    logPrintNum(1, 0);
    
    // 결과
    Enter logPrintNum 1
    Exit  logPrintNum 1
    undefined
    1

    위와 같은 경우 코드의 순서와 결과가 일치하지 않는 것입니다..

    이러한 콜스택에 비었을 때 큐스택에서 하나씩 꺼내어서 다시 이벤트 루프에서 다시 콜스택에 쌓여서 실행되는 문제점을 해결하기 위해

    그리고 콜백함수의 지옥을 해결하기 위해 promise가 나오고 이어서 async / await가 나온 것입니다.

     

    async 키워드는 항상 함수 앞에 붙고, 항상 promise를 리턴합니다.

     

    await는 항상 async 함수 내에서만 사용할 수 있으며, resolve또는 reject를 리턴합니다.

     

    그 흐름에 따라서 위의 코드를 고쳐 보면 다음과 같은 결과가 출력됩니다.

    let printNum = async (number, delaySec) => {
        await setTimeout(() => console.log(number), delaySec); // i/o 작업을 대신한다.
    };
    
    let logPrintNum = async (number, delaySec) => {
        console.log(`Enter logPrintNum ${number}`);
        await printNum(number, delaySec);
        console.log(`Exit  logPrintNum ${number}`);
    };
    
    logPrintNum(1, 0);
    
    // 결과
    Enter logPrintNum 1
    Exit  logPrintNum 1
    Promise {<resolved>: undefined}
    1

    위와 똑같습니다. 달라진게 없습니다.

     

    이유는 setTimeOut이 Promise를 리턴하고 하고 있지 않기 때문입니다.

    await은 오직 Promise에 대해서만 유효합니다.

     

    let printNum = (number, delaySec) => {
        return new Promise((resolve) =>
            setTimeout(() => {
                console.log(number);
                resolve();
            }, delaySec));
    };
    
    let logPrintNum = async (number, delaySec) => {
        console.log(`Enter logPrintNum ${number}`);
        await printNum(number, delaySec);
        console.log(`Exit  logPrintNum ${number}`);
    };
    
    logPrintNum(1, 0);
    
    // 결과
    
    Enter logPrintNum 1
    Promise {<pending>}
    1
    Exit  logPrintNum 1

    이번에는 제대로 나옵니다.

    프로미스는 생성자로 콜백함수를 받게 됩니다. 해당 콜백 함수의 첫 번째 인자는 resolve가 됩니다.

    resolve가 리턴됨으로 인해서 logPrintNum의 함수내의 await는 resolve가 호출되었음을 알고 그 함수 호출부분으로 다음으로 넘어가게 됩니다.

     

     

    map에서의 async / await

    map 이나 forEach는 순회함수인데 중간에 async를 만났다고 해서 await가 resolve 또는 reject 리턴을 기다리지 않습니다.

    map의 파라미터로 async 함수를 넣어 주면 promise 객체 자체가 리턴되게 됩니다.

     

     

    출처 : https://velog.io/@litien/AsyncAwait-%EC%A3%BC%EC%9D%98%ED%95%B4%EC%84%9C-%EB%8B%A4%EB%A3%A8%EA%B8%B0?fbclid=IwAR32EMT_F0aMJI9s3PWGulPx-qugXoLfSyiBmrC12XutCkE2IWgrf7HC0eU

Designed by Tistory.