본문 바로가기
개발/Javascript

[프론트엔드 예상 면접] Promise와 Async/await 차이점

by 코딩하는 갓디노 2024. 8. 13.

[프론트엔드 면접] Promise와 Async/await 차이점

 

💡둘 다 자바스크립트에서 비동기작업을 위한 것
Promise는 작업실행 후 revolve, reject를 성공, 실패로 반환하여 이를 then, catch로 받아 완료 후의 동작을 정의
Async/await는 Promise의 완료를 기다리기 위한 문법으로 더 간단하게 만듦
Async가 함수 앞에 붙으면 promise를 반환하고, 이 promise 앞에 await가 붙어 있으면 해당 promise가 완료될 때까지 코드 실행이 일시 중지가 되어 동기처럼 쓸 수 있음
간단한 비동기 처리 또는 여러 작업을 병렬로 실행해야 하는 경우 Promise.all() 메서드 사용하는 경우, Promise를 사용
복잡한 비동기 흐름으로 직관적이고 가독성 높은 코드가 필요한 경우 async/await을 사용

 

Promise

  • 비동기 작업(내용이 실행은 되었지만 결과를 아직 반환하지 않은 객체)의 완료 또는 실패를 나타내는 객체
  • 비동기 작업 완료 후 성공하면 resolve, 실패하면 reject 상태를 반환
  • revolve 후 then 메소드으로 연결하여 성공 후 동작 처리, reject 후 catch 메소드로 연결하여 에러 처리, fianlly는 성공하거나 실패하더라도 무조건 실행
  // Promise를 이용한 비동기 함수
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = { id: 1, message: "Hello, World!" };
      resolve(data);
    }, 2000);
  });
}

// Promise 사용
fetchData()
  .then((result) => {
    console.log("Data fetched:", result);
  })
  .catch((error) => {
    console.error("Error fetching data:", error);
  })
  .finally(() => {
    console.log("Fetch operation completed.");
  });

 

Promoise 장/단점

장점

  • 체이닝(Chaining): Promise는 .then(), .catch(), .finally() 메서드를 사용해 비동기 작업을 체이닝 방식으로 처리할 수 있습니다. 이로 인해 여러 비동기 작업을 순차적으로 실행하거나, 조건에 따라 다르게 처리할 수 있습니다.
  • 비동기 흐름 제어: Promise.all(), Promise.race() 등을 사용하면 여러 비동기 작업을 병렬로 실행하거나, 특정 작업이 먼저 완료되면 결과를 처리하는 등의 제어가 가능합니다.

단점

  • 가독성 문제: 여러 비동기 작업이 중첩되면 .then() 체인이 길어져 코드가 복잡하고 가독성이 떨어질 수 있습니다. 이는 이른바 "콜백 지옥"과 유사한 문제를 야기할 수 있습니다.
  • 에러 처리: 에러 처리를 위한 .catch()를 사용해야 하며, 체인 내에서 발생하는 에러를 놓칠 가능성이 있습니다. 또한, 체인이 길어지면 에러 처리가 복잡해질 수 있습니다.

 

Async/await

  • Promise 기반의 비동기 코드를 보다 직관적이고, 동기 코드처럼 작성할 수 있게 해줌
  • async 키워드를 함수 앞에 붙이면 해당 함수는 Promise를 반환하고, Promiese 앞에 await 키워드를 사용하면 Promise가 완료될 때까지 코드의 실행이 일시 중지되어 동기처럼 작동
  • await는 Async 함수 내에서만 사용할 수 있습니다.
  • 변수 = await 프로미스; 인 경우 resolve된 값이 변수에 저장됨
  • 변수 await 값; 인 경우 그 값이 변수에 저장
  • await가 Promise의 then 역할을 하면서 코드가 짧아짐
  • Async function 의 return 값은 무조건 .then() 으로 받음
  • 주의할 점: reject 처리하는 것이 없어 에러 핸들링은 try, catch문으로 처리
async function fetchdata() {
	 try {
		 const response = await fetch('https://api.example.com/data'); //비동기 요청
		 const data = await response.json(); //응답 처리
	 } catch {
		 console.error('fetch error:', error) //오류 처리
	 }
}

 

Async/await 장/단점

장점:

  • 가독성: async/await는 동기 코드처럼 비동기 작업을 작성할 수 있기 때문에, 코드의 가독성이 높아지고 직관적입니다. 이는 특히 복잡한 비동기 로직을 다룰 때 코드의 이해와 유지보수를 용이하게 합니다.
  • 에러 처리: try/catch 블록을 사용하여 비동기 작업에서 발생하는 에러를 동기 코드처럼 처리할 수 있습니다. 이로 인해 에러 처리 코드가 더욱 일관되고 간결해집니다.

단점:

  • 병렬 처리의 어려움: await는 기본적으로 비동기 작업을 순차적으로 처리합니다. 여러 작업을 병렬로 실행하려면 Promise.all()과 같은 방법을 사용해야 하며, 이를 사용하지 않으면 비효율적인 코드가 될 수 있습니다.
  • 트랜스파일러 필요성: async/await는 ES2017(ES8)에서 도입된 기능으로, 구형 브라우저에서는 트랜스파일러(Babel 등)를 사용해야 지원이 가능합니다.

 

Promise와 Async/await 차이점

  1. 코드 가독성 및 간결성:
    • Promise를 사용하면 then, catch 체인을 통해 비동기 작업의 흐름을 처리해야 합니다. 반면, async/await를 사용하면 동기 코드처럼 순차적으로 작성할 수 있어 가독성이 높아집니다.
  2. 에러 처리:
    • Promise에서는 catch() 메서드를 사용해 에러를 처리합니다. async/await에서는 try/catch 블록을 사용해 에러를 처리할 수 있어, 동기 코드의 에러 처리 방식과 유사합니다.
  3. 동작 방식:
    • Promise는 비동기 작업의 결과에 따라 resolve 또는 reject가 호출되며, 그 결과는 then이나 catch를 통해 처리됩니다.
    • async/await는 await가 Promise가 완료될 때까지 기다린 다음, 그 결과를 반환하거나 에러가 발생하면 catch로 처리할 수 있습니다.
  4. 구현 복잡도:
    • async/await는 복잡한 비동기 흐름을 간단하게 표현(코드 축약)할 수 있게 해주지만, Promise는 비동기 작업이 중첩되거나 여러 작업이 병렬로 실행되어야 하는 경우 가독성이 좋고 더 유연하게 사용할 수 있습니다.

 

언제 Promise를 사용해야 하는가?

  • 단순한 비동기 체이닝: 여러 개의 비동기 작업을 순차적으로 실행하거나 병렬로 실행할 때, 특히 Promise.all()과 같은 메서드를 활용하는 경우 Promise가 더 적합할 수 있습니다.
  • 병렬 작업: 여러 비동기 작업을 동시에 시작하고, 모든 작업이 완료되거나 가장 빠른 작업이 완료되면 결과를 처리해야 할 때 Promise의 기능이 유용합니다.

 

언제 async/await을 사용해야 하는가?

  • 복잡한 비동기 로직: 여러 비동기 작업이 연속적으로 실행되어야 하고, 각 작업 간의 결과가 다음 작업에 의존하는 경우, async/await을 사용하면 코드를 더욱 읽기 쉽고, 유지보수하기 쉽게 만들 수 있습니다.
  • 에러 처리가 중요한 경우: 비동기 작업에서 발생하는 에러를 일관되게 처리해야 할 때 async/await과 try/catch 구조가 더 나은 방법을 제공합니다.
  • 코드 가독성: 가독성이 중요한 프로젝트나 팀 환경에서 async/await을 사용하면 코드가 직관적이고 명확해져 유지보수성이 향상됩니다.

 

결론 및 추천

  • 간단한 비동기 처리: 비동기 작업이 복잡하지 않고, 여러 작업을 병렬로 실행해야 하는 경우 Promise를 사용하세요.
  • 복잡한 비동기 흐름: 비동기 작업 간의 의존성이 많고, 직관적이고 가독성 높은 코드가 필요한 경우 async/await을 사용하는 것이 좋습니다.
반응형

댓글