ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Express] router에서 async await callback사용하기
    programing/Language 2019. 2. 6. 00:02


    안녕하세요, Einere입니다.

    (ADblock을 꺼주시면 감사하겠습니다.)


    오늘은 Express의 router에서 async await를 활용한 callback을 사용하는 법을 알아보도록 하겠습니다.




    Async / Await

    const asyncFunction = () => {
      return new Promise(resolve => {
        setTimeout(_ => {
          resolve({ message: 'success' });
        }, 3000);
      });
    };

    테스트용 비동기 함수입니다.



    app.use('/async-function', async (req, res) => {
      const result = await asyncFunction();
      res.json(result);
    });

    실제 router에는 위와 같이 callback용 익명함수 앞에 async키워드를 붙이시면 됩니다.

    await 키워드는 async함수 내에서만 사용이 가능하기 때문이죠.




    Error handling

    app.use('/async-function', async (req, res, next) => {
      try {
        const result = await asyncFunction();
        throw new Error('Async 사용자 정의 에러 발생');
        res.json(result);
      } catch (error) {
        next(error);
      }
    });
    router는 async키워드를 붙인 callback함수 내의 error(혹은 exception)을 감지하지 못합니다.
    따라서, 위와 같이 try catch문을 이용해서 에러를 핸들링해줘야 합니다.





    Refactoring

    위와 같이 try catch문으로 에러를 핸들링한다고 해도, 모든 callback마다 try catch문을 사용하는 것은 꽤나 지저분합니다.
    리팩토링하여 간편한 interface인 wrapper함수를 만들어 봅시다.

    const wrapper = asyncFn => {
      return (async (req, res, next) => {
        try {
          return await asyncFn(req, res, next);
        } catch (error) {
          return next(error);
        }
      });
    };

    warpper함수는 error handling에서 만든 async callback함수를 반환하는 간단한 함수입니다.

    인자로 async function을 받아서, callback함수 내에서 해당 함수를 실행합니다.

    예외처리를 하기 위해 try catch문도 사용합니다.


    실제로 router에 사용한다면 아래와 같이 사용하면 됩니다.


    app.use('/async-function', wrapper(async (req, res, next) => {
      // await가 필요한 작업을 합니다.
    }))

    wrapper함수의 인자로 "await가 필요한 로직을 담고 있는 callback함수"를 주게 됩니다.

    그러면 "try catch문이 있는 async 함수"를 반환합니다.

    "try catch문이 있는 async 함수"는 인자로 받았던, "await가 필요한 로직을 담고 있는 callback함수"(즉, asyncFn)의 결과를 기다렸다가 반환합니다.

    "asyncFn"내에서 promise관련 에러가 발생한다면 하위 스택의 "try catch문이 있는 async 함수"의 catch에 걸려 next()를 반환하게 됩니다.

    promise관련 에러가 발생하지 않는다면 "asyncFn"를 정상적으로 마치고, 하위 스택의 "try catch문이 있는 async 함수"의 try catch문을 빠져나와서 다음 middleware에 가지 않고 끝나게 됩니다.



    참고


    댓글

Designed by black7375.