프로미스(Promise)와 async/await란?

2023. 5. 9. 14:22프론트엔드/기술 면접 (JavaScript Interview Questions)

반응형

<참고>

**자바스크립트의 비동기 처리란 “특정 로직의 실행이 끝날 때까지 기다려주지 않고, 나머지 코드를 먼저 실행하는 것”을 의미합니다. (즉, 아래 #2번에서 실행이 끝날 때까지 안 기다려주고, 바로 #3번을 먼저 실행하는 것)

 

ex) 자바스크립트에서 비동기 처리가 필요한 이유를 생각해보면, 화면에서 서버로 데이터를 요청했을 때, 서버가 언제 그 요청에 대한 응답을 줄지도 모르는데 마냥 다른 코드를 실행 안 하고 기다릴 순 없기 때문입니다.

Promise

Promise란 비동기 작업이 종료된 후에,

  1. 실행이 잘 성공했는지
  2. 혹은 실패했는지
  3. 성공 또는 실패의 결과값이 무엇인지

위 세가지 내용을 미래(비동기 작업이 종료된 후)에 반환해주겠다고 약속해주는 객체이다.

(A promise is a good way to handle asynchronous operations. It is used to find out if the asynchronous operation is successfully completed or not.)

 

Promise는 new Promise()로 프로미스를 생성하고 종료될 때까지 3가지 상태를 가집니다:

  1. 대기(pending): 이행하지도 않았고, 거부하지도 않은 초기 상태 (initial state, neither fulfilled nor rejected.)
  2. 이행, 수행함(fulfilled): 연산이 성공적으로 완료 (the operation was completed successfully.)
  3. 거부(rejected): 연산이 실패 (the operation failed.)

then() 메소드는 프로미스가 이행(fulfilled)되었을 때 실행되는 함수고, 인자로 promise의 결괏값을 받습니다.

catch() 메소드는 프로미스가 거부(rejected)되었을 때 실행되는 함수고, 인자로 거부 결괏값을 받습니다.

finally() 메소드는 프로미스의 성공과 실패에 상관없이 종료만 되면 실행되는 함수다. 따라서 프로미스가 성공인지 실패인지는 알 수 없다.

 

콜백 지옥(callback hell)을 해결하려고 나온 것이, Promise.

 

Async와 Await

async await은 자바스크립트의 비동기 처리 패턴 중 가장 최근에 나온 문법입니다. 기존의 비동기 처리 방식인 콜백 함수(단점: 함수의 처리 순서를 보장하기 위해서 함수를 중첩하게 사용되는 경우가 발생해, 콜백헬이 발생, 에러 처리가 힘듦)프로미스(후속 처리 메서드-then, catch, finally 없이 async/await을 쓰면 마치 동기 처리처럼 프로미스가 처리 결과를 반환)의 단점을 보완하고 개발자가 읽기 좋은 코드를 작성할 수 있게 도와줍니다.

 

예시

문법

주의해야 할 점: 비동기_처리_메서드는 반드시 Promise 객체를 반환해야 await가 의도한 대로 동작합니다.

 

function fetchNames() {
  return new Promise(function(resolve, reject) {
    const names = ['John', 'Bob', 'Roy'];
    resolve(names)
  });
}

async function logNames() {
  var resultNames = await fetchNames();
  console.log(resultNames); // ['John', 'Bob', 'Roy']
}

예외 처리

프로미스에서 에러 처리를 위해 .catch()를 썼듯이, async에서는 catch { } 블락을 쓰면 됩니다.

async function logNames() {
  try {
    const user = await fetchUser();
    if (user.id === 123) {
      const fullName = await fetchName();
      console.log(fullName.first); // 'John'
    }
  } catch (error) {
    console.log(error);
  }
}

네트워크 통신 오류뿐만 아니라 간단한 타입 오류 등의 일반적인 오류까지도 catch로 잡아낼 수 있습니다. 발견된 에러는 error 객체에 담기기 때문에 에러의 유형에 맞게 에러 코드를 처리해주면 됩니다.

 

반응형