JavaScript/JavaScript 문법

[JavaScript]async, await 예외 처리

DevStory 2022. 3. 27.

일반적인 예외처리

다음은 자바스크립트(JavaScript)에서 일반적인 예외처리입니다.

function goThrows() {
  throw new Error('throw new Error from goThrows()');  
}

function run() {
  try {
    goThrows();
  } catch(err) {
    console.error('catch from run()');
    console.error(err);
  } finally {
    console.log('finally from run()');
  }
}

run();
// catch from run() 
// Error: throw new Error from goThrows()
// finally from run()

run() 함수는 예외를 강제로 발생시키는 goThrows() 함수를 호출합니다. run() 함수의 try문에서 오류를 포착하여 catch문이 실행되었으며, try...catch문이 끝나고 finally문이 실행됩니다.


비동기 함수에서 예외 발생

async 키워드를 사용하여 goThrows() 함수를 비동기 함수로 정의합니다. 그리고 비동기 함수에서 예외를 강제로 발생시키도록 합니다. 여기서 꼭 기억해야 하는 내용이 있습니다.

async 함수는 항상 Promise를 반환합니다.
  • 비동기 함수는 작업을 성공적으로 처리하면 Promise.Resolve()를 반환합니다.
  • 비동기 함수는 작업이 실패하거나 오류가 발생하면 Promise.Reject()를 반환합니다.
async function goThrows() {
  console.log('goThrows start...');
  throw new Error('throw new Error form goThrows()');  
}

function run() {
  try {
    console.log("try block start...");
    goThrows();
    console.log("try block end...");
  } catch(err) {
    console.error('catch from run()');
    console.error(err);
  } finally {
    console.log('finally from run()');
  }
}

run();
// try block start...
// goThrows start...
// try block end...
// finally from run()
// 화면 에러 발생...

위 예제를 실행하면 다음과 같이 화면에서 에러가 발생하는 것을 확인할 수 있습니다.

이제 비동기 함수의 문제를 확인할 수 있습니다. async 키워드를 사용하여 비동기 함수를 정의하고 비동기 함수에서 예외 또는 오류가 발생하는 경우 try...catch문에서 오류를 잡을 수 없습니다.

run() 함수는 비동기 함수 goThows()가 Promise 객체를 전달하는 과정을 기다리지 않고 finally문이 먼저 실행되므로 거부된 Prmise 객체를 처리할 수 없습니다.

반응형

해결 방법

비동기 함수의 예외를 캐치하기 위해서는 다음 두 가지 방법이 존재합니다.

  • await 키워드를 사용하여 비동기 함수를 기다립니다.
  • 비동기 함수 호출에서 catch문을 연결합니다.

첫 번째 방법으로 await 키워드를 사용하는 방법입니다. 비동기 함수를 호출하는 코드에서 비동기 함수 앞에 await 키워드를 붙입니다. 그리고 await 키워드를 사용하는 함수에도 async 키워드를 붙입니다.

async function goThrows() {
  console.log('goThrows start...');
  throw new Error('throw new Error form goThrows()');  
}

// await를 사용하기 위해 async 키워드 사용
async function run() {
  try {
    console.log("try block start...");
    // 비동기 함수 앞에 await 키워드 사용
    await goThrows();
    console.log("try block end...");
  } catch(err) {
    console.error('catch from run()');
    console.error(err);
  } finally {
    console.log('finally from run()');
  }
}

run();
// try block start...
// catch from run()
// Error: throw new Error from goThrows()
// finally from run()

​두 번째 방법으로 비동기 함수 호출에서 catch문을 연결합니다.

async function goThrows() {
  throw new Error("throw new Error from goThrows()");
}

function run() {
  console.log("run start...");
  goThrows()
    .catch((err) => {
      console.error("catch from run()");
      console.error(err);
    })
    .then(() => console.log('finally from run()'));
  console.log("run end...");
}

run();
// run start... 
// run end... 
// catch from run()
// Error: throw new Error from goThrows()
// finally from run()

run() 함수에서 try...catch...finally문이 사라졌고 goThrows() 호출 뒤에 .catch()문을 연결하여 비동기 함수의 예외를 처리합니다. 두 번째 방법보다 await를 사용하는 첫 번째 방법이 심플하고 간결합니다.


정리

  • async는 항상 Promise 객체를 반환합니다.
  • async/await.catch()문을 사용하여 비동기 함수의 예외를 처리할 수 있습니다.
반응형

댓글