써치킴의 우당탕탕 개발 블로그

[Vue.js][Ch4][영화검색 사이트] 비동기 - 예외처리(then, catch, finally) 본문

완벽하게 Vue.js

[Vue.js][Ch4][영화검색 사이트] 비동기 - 예외처리(then, catch, finally)

써치킴 2022. 4. 25. 02:47

Promise

약속의 객체

비동기를 통해서 로직을 기다렸다가, 처리가 완료되거나 실패하면 그 결과 값을 반환한다.

Promise는 다음 중 하나의 상태를 가진다.

  • 대기(pending): 이행하지도, 거부하지도 않은 초기 상태.
  • 이행(fulfilled): 연산이 성공적으로 완료됨.
  • 거부(rejected): 연산이 실패함.

main.js

function a() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('A');
      resolve();
    }, 1000);
  })
}

async function test() {
  await a();
  console.log('B');
}

test();

상단 코드에서 async, await 키워드를 사용할 수 없는 경우, 어떻게 비동기를 처리할 것인지 확인해보자.

then 메서드 활용

function a() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('A');
      resolve();
    }, 1000);
  })
}

function test() {
  const promise =  a();   // a 함수를 실행하고 promise 객체를 반환
  promise.then(() => {    // then 메서드에서 콜백으로 함수 추가
    console.log('B');     // => a 함수가 실행되고 then 메서드의 콜백함수가 실행된다.
  })
}

test();

a 함수가 실행되는 위치에서 promise 객체가 반환되므로 특정 변수에 담지 않아도 then 메서드를 사용할 수 있다.

function a() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('A');
      resolve();
    }, 1000);
  })
}

function test() {
  a().then(() => {    
    console.log('B');   
  });
  
}

test();

A, B, C, D, Done!를 출력해보자.

function a() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('A');
      resolve();
    }, 1000);
  })
}

function b() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('B');
      resolve();
    }, 1000);
  })
}

function c() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('C');
      resolve();
    }, 1000);
  })
}

function d() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('D');
      resolve();
    }, 1000);
  })
}

function test() {
  a().then(() => {    
    b().then(() => {
      c().then(() => {
        d().then(() => {
          console.log('Done!');
        })
      })
    })
  });
  
}

test();

해당 패턴은 잘 동작하지만, 콜백 지옥과 유사하기 때문에 권장하지 않는다.

then 메서드 뒤에 메서드 체이닝으로 then 메서드를 사용할 수 있게 promise를 반환한다.

function test() {
  a().then(() => {    
    return b();   // promise 객체 반환 => a.then 뒤에 then을 사용할 수 있다.
  }).then(() => {
    return c();
  }).then(() => {
    return d();
  }).then(() => {
    console.log('Done');
  }) 
}

화살표함수는 중괄호와 return 키워드를 생략할 수 있다.

{ return } 생략

function test() {
  a()
    .then(() => b())
    .then(() => c())
    .then(() => d())
    .then(() => {
    console.log('Done');
  }); 
}

then 메서드 패턴은 복잡하므로 async, await 패턴을 사용하는 것을 권장한다!


reject

promise의 callback 함수 내 로직이 정상적으로 실행될 수 없을 때 호출한다.

function a(number) {
  return new Promise((resolve, reject) => {
    if (number > 4) {
      reject();   // 로직을 정상적으로 처리하지 않겠다 => 거부하겠다라는 의미로 호출
                  // reject이 실행되면 resolve는 실행되지 않는다.
      return;     // 함수를 종료시킴
    }
    setTimeout(() => {
      console.log('A');
      resolve();
    }, 1000);
  })
}

function test() {
  a(7)
  .then(() => {     // 함수가 정상 처리되고 나서 실행
    console.log('resolve!');
  })
  .catch(() => {    // 함수가 실행을 거부하고 나서 실행
    console.log('reject!');
  })
  .finally(() => {  // resolve, reject 상관없이 무조건 마지막에 실행
    console.log('Done!');
  })
}

test();
  • reject는 '거부하겠다'라는 의미이다.
  • reject이 실행되면 resolve는 실행되지 않는다.
  • .then() : 함수가 정상 처리되고 나서 실행
  • .catch() : 함수가 실행을 거부하고 나서 실행
  • .finally() : resolve, reject 상관없이 무조건 마지막에 실행

상단 예외처리를 async, await에선 어떻게 비동기처리할 것인가?

async function test() {
  await a(8);
  console.log('Done!');
}

 

8은 4보다 크기 때문에

reject로 거부되었고,

로직을 정상적으로 처리할 수 없기 때문에

javascript 에러가 발생한다.

=> try catch 문을 사용한다.

 

 

async function test() {
   try {
    await a(8);
    console.log('Resolve');
  } catch (error) {
    console.log('Reject');
  } finally {
    console.log('Done!');
  }
}

에러가 발생할 수도 있는 코드는 try문에 작성하고, 에러가 발생하면 catch문에 넘겨서 예외처리한다.

Comments