티스토리

  • Taak-e's Dev-Log (48)
    • Computer Sceience (6)
      • 알고리즘 & 자료구조 (0)
      • Computer Architecture (1)
      • etc. (5)
    • Language (6)
      • HTML & CSS (0)
      • JavaScript (6)
      • TypeScript (0)
    • Library & Framework (10)
      • React.js (5)
      • Redux (4)
      • Vite (0)
      • SWR (0)
      • Jest & RTL (1)
    • Infra & Tool (4)
      • AWS (1)
      • Git & Github (2)
      • VScode (0)
      • etc. (1)
    • Experience (22)
      • 원티드 프리온보딩 (7)
      • 부트캠프 by 항해99 (15)
전체 방문자
오늘
어제

인기 글

태그

  • 소프트웨어 테스트 종류
  • Array-like objects
  • React-Saga
  • 프리온보딩 프론트엔드
  • HTTP 통신에서 횡단 관심사 처리
  • 리액트 테스트
  • React-Saga 사용 이유
  • Redux DevTools
  • 유사 배열
  • 프리온보딩
  • Generator function
  • 테스트 주도 개발법
  • Iterable protocol
  • redux middleware
  • 차이점
  • React-Saga 활용법
  • 자바스크립트 비동기
  • 항해99
  • 프리온보딩 회고
  • 프리온보딩 기업협업과제 회고
  • 비동기
  • Middleware 가 없이 동작한다면?
  • Redux 구성요소
  • Redux 모듈
  • dependecy array
  • Middleware 사용하는 이유
  • Redux 원칙 3가지
  • 유사 배열 객체
  • 원티드 프리온보딩 회고
  • 원티드 프리온보딩
hELLO · Designed By 정상우.
Taak-e (탁이)

Dev.log ( Taak-e )

Promise & Async Await
Language/JavaScript

Promise & Async Await

2022. 11. 10. 15:04
반응형

1. Promise - 비동기를 값으로 다루는 법

Promise 란?

  • 자바스크립트가 미리 만들어둔 하나의 객체
  • 이 객체는 then, catch 라는 메서드를 가지고 있다.
  • pending, fulfilled, rejected 세가지 상태를 가지고 있다.

Promise는 최초에 pending 상태로 만들어진다. 그리고 이후 fulfilled 또는 rejected 상태로 변경시킬 수 있다. Promise를 만들기 위해서는 new Promise 키워드를 통해서 만들 수 있는데 이때 콜백함수를 인자로 넣을 수 있다.

new Promise((resolve, reject) => {})

이때 콜백 안에서 resolve 함수를 호출하면 Promise는 value와 함께 fulfilled 상태가 된다. 반대로 reject 함수를 호출하면 Promise는 reason과 함께 rejected 상태가 된다. 그리고 fulfilled 또는 rejected 상태가 된 Promise는 then 메서드의 콜백함수를 호출한다.

then 메서드는 두개의 인자를 받는다.

then(onResolved, onRejected);

각각 promise가 resolve되거나, reject되었을 때 실행할 콜백함수를 인자로 받으며, then은 promise의 상태에 따라서 value를 onResolved 함수의 인자로 넣어서 호출하거나, reason을 onRejected 함수의 인자로 넣어서 호출해준다.

const pr = new Promise((resolve, reject) => {
    setTimeout(()=>resolve("Hello"), 1000)
})

pr.then(console.log)

위 코드에서 pr이라는 이름의 Promise는 1000ms 후에 fulfilled 상태로 변하게되고, 따라서 then 메서드가 호출되면서 then의 콜백이 실행되고, 콜백함수에는 fulfilled된 promise의 value가 인자로 전달된다.

const pr = new Promise((resolve, reject) => {
    setTimeout(()=>reject("Something went wrong"), 1000)
})

pr.then(console.log, console.error)

위 코드에서는 pr은 reject 되었기에, 두번째 콜백함수가 실행되게 된다.

하지만 reject된 Promise를 처리하기에 더 쉬운 방법은 catch 메서드를 사용하는 것이다. catch 메서드는 promise가 reject 되었을때만 실행되며, then 에서 에러를 처리하는 것 보다 가독성이 더 좋으며, then의 callback에서 발생한 에러도 잡아낼 수 있기에 catch를 사용해서 처리하는것이 권장된다.

const pr = new Promise((resolve, reject) => {
    setTimeout(() => reject("Something went wrong"), 1000)
})

pr.then(console.log).catch(console.error);

 

2. Async-Await

Promise도 근본적으로 then 을 이용해서 callback을 깊어지지 않게 만들어졌다는 것 뿐, 콜백패턴을 사용하고 있단 것은 변하지 않았다. 이런 상황에서 실제 동작은 비동기적으로 이루어지지만, 코드의 흐름은 동기적으로 보이도록해서 개발자가 흐름을 파악하기 쉽게 만드는 방법을 고민하게 되었고 그 결과 Async-Await 문법이 탄생했다.

Async-Await는 Promise를 기반으로 동작한다. 따라서 Promise에 대한 이해없이는 제대로 사용하기 어렵다. 자바스크립트에서는 async 함수를 선언할 수 있으며 함수 앞에 async라는 키워드를 붙여서 선언한다.

async function some(){}

async 함수의 리턴값은 항상 Promise이다. 함수 내부에서 Promise를 return하지 않더라도, 모든 return value를 암묵적으로 Promise로 감싸서 내보내는 동작을 수행한다.

그리고 async 함수 내부에서는 await 키워드를 사용할 수 있다.

async function getData(){
  const response = await fetchSomeData();
  const data = await response.json();
  return data
}

await는 Promise가 settled 될 때까지 함수의 실행을 잠시 멈추고 대기해준다. 그 후 Promise가 settled된다면 함수를 계속 실행시켜준다. 이런 동작을 통해서 마치 async 함수 내의 코드의 흐름을 동기적으로 생각하면서 작성할 수 있기에 개발자가 함수의 흐름을 파악하기 쉬워진다는 장점이 있다.

또한 async 함수에서는 await 중인 promise가 reject된 경우에는 이를 예외로 던져준다. 따라서 async 함수에서는 try, catch 블록을 이용해서 발생한 예외를 처리할 수 있게 된다.

async function getData(){
  try {
    const response = await fetchSomeData();
    const data = await response.json();
    return data
  } catch (e) {
    console.error(e)
  }
}

 

3. Promise 고급 활용

1) Promise.all()

  • 인자로 Promise의 배열을 받는다. resolve된 value들의 배열을 가진 Promise를 리턴
  • 인자로 받은 Promise 중 하나라도 reject 된다면, 동작을 중지하며 reject된 Promise를 리턴
const delay = (ms) => {
  return new Promise((resolve) => {
    setTimeout(() => resolve(`completed in ${ms}`), ms);
  });
};

async function withoutPromiseAll() {
  await delay(1000);
  await delay(1000);
  await delay(1000);
}

async function withPromiseAll() {
  await Promise.all([delay(1000), delay(1000), delay(1000)]);
}

2) Promise.allSettled()

  • Promise.all의 동작과 유사하고 단, reject된 promise가 있더라도 전체를 모두 처리해서 배열에 담아준다.
  • 배열 안의 요소들은 각기 status와 value 또는 reason 프로퍼티를 가진 객체
const pr1 = Promise.resolve(1);
const pr2 = Promise.reject("rejected");

Promise.allSettled([pr1, pr2]).then(console.log)
/*
	[
	  { status: 'fulfilled', value: 1 },
	  { status: 'rejected', reason: 'rejected' }
	]
*/

3) Promise.race()

  • 인자로 Promise의 배열을 받고, 그 중 가장 먼저 resolve되거나 reject된 promise를 반환한다.
const pr1 = new Promise((resolve) => setTimeout(() => resolve(1), 1000));
const pr2 = new Promise((resolve) => setTimeout(() => resolve(2), 50));

Promise.race([pr1, pr2]).then(console.log);

 

반응형
저작자표시 (새창열림)

'Language > JavaScript' 카테고리의 다른 글

[JavaScript] 비동기를 구현하는 방법 (Event loop & Callback)  (0) 2022.11.09
비동기에 대해서  (0) 2022.11.08
Iterator & Generator  (0) 2022.10.29
Javascript ES6 전체적으로 살펴보기  (0) 2022.06.27
[JavaScript] 유사 배열 객체(Array-like objects)  (0) 2022.03.23
    'Language/JavaScript' 카테고리의 다른 글
    • [JavaScript] 비동기를 구현하는 방법 (Event loop & Callback)
    • 비동기에 대해서
    • Iterator & Generator
    • Javascript ES6 전체적으로 살펴보기
    Taak-e (탁이)
    Taak-e (탁이)
    프론트엔드 개발자 Taak-e (탁이) 입니다! 개발자 분들과 '함께 자라기' 위한 정확히 알고 설명할 수 있는 지식에 대해서는 기록하고 공유하기를 원합니다.

    티스토리툴바