본문 바로가기
Books/모던 JS Deep Dive ✔️

[모던 JS Deep Dive] 45장 - 프로미스

by Aaron-Kim 2022. 1. 27.

45.1 비동기 처리를 위한 콜백 패턴의 단점

  - 콜백 헬

    - 비동기 함수: 함수 내부에 비동기로 동작하는 코드를 포함한 함수 ex. setTimeout 함수

    - 비동기 함수 내의 이벤트 핸들러는 이벤트가 발생하면 일단 태스크 큐에 저장되어 대기하다가,

      콜 스택이 비면 이벤트 루프에 의해 콜 스택으로 푸시되어 실행됨

    - 비동기 함수는 비동기 처리 결과를 외부에 반환 불가, 상위 스코프의 변수에 할당 불가

    - 비동기 함수의 처리 결과(서버 응답 등)에 대한 후속 처리는 비동기 함수 내부에서 수행해야 함

    - 일반적으로 비동기 함수 내부에 비동기 처리 결과에 대한 후속 처리 위한 콜백 함수 전달함

    - 콜백 헬: 콜백 함수를 통해 비동기 처리 결과에 대한 후속 처리를 수행하는 비동기 함수가

      비동기 처리 결과를 가지고 또 다시 비동기 함수를 호출해야 한다면 콜백 함수 호출이 중첩되어

      복잡도가 높아지는 현상

  - 에러 처리의 한계

    - 에러는 caller 방향으로 전파됨

    - 비동기 함수 내의 콜백 함수가 발생시킨 에러 처리 곤란

    - ES6 프로미스 도입

45.2 프로미스의 생성

  - Promise 생성자 함수를 new 연산자와 함께 호출 (ECMAScript 사양에 정의된 표준 빌트인 객체)

    - 비동기 처리를 수행할 콜백 함수를 인수로 전달받음

    - 콜백 함수는 resolve와 reject 함수를 인수로 전달받음 (콜백 함수 내부에서 비동기 처리 수행)

    - 비동기 처리 성공 시 resolve 함수 호출, 비동기 처리 실패 시 reject 함수 호출

  - 프로미스 상태 정보

    - pending: 비동기 처리가 아직 수행되지 않은 상태, 프로미스 생성 직후 기본 상태

    - fulfilled: 비동기 처리가 수행된 상태(성공), resolve 함수 호출

    - rejected: 비동기 처리가 수행된 상태(실패), reject 함수 호출

  - 프로미스는 비동기 처리 상태와 처리 결과를 관리하는 객체임

45.3 프로미스의 후속 처리 메서드

  - Promise.prototype.then 메서드

    - 두 개의 콜백 함수를 인수로 전달받음

      - 첫 번째 콜백 함수: 비동기 처리 성공 시 호출되는 성공 처리 콜백 함수

      - 두 번째 콜백 함수: 비동기 처리 실패 시 호출되는 실패 처리 콜백 함수

    - 언제나 프로미스 반환

  - Promise.prototype.catch 메서드

    - 한 개의 콜백 함수를 인수로 전달받음

      - 콜백 함수는 프로미스가 rejected 상태인 경우만 호출됨

    - 언제나 프로미스 반환

  - Promise.prototype.finally 메서드

    - 한 개의 콜백 함수를 인수로 전달받음

    - 프로미스의 성공(fulfilled) 또는 실패(rejected) 상관없이 무조건 한 번 호출됨

    - 프로미스의 상태와 상관없이 공통적으로 수행해야 할 처리 내용 있을 때 유용

    - 언제나 프로미스 반환

45.4 프로미스의 에러 처리

  - 비동기 처리에서 발생한 에러는 프로미스 then 메서드의 두 번째 콜백 함수로 처리 가능

    - 첫 번째 콜백 함수에서 발생한 에러 캐치 불가

    - 코드 복잡해지고 가독성 안좋음

  - 프로미스 catch 메서드를 사용해 처리 가능

    - 내부적으로 then(undefined, onRejected) 호출

    - 모든 then 메서드 호출 이후에 catch 메서드 호출하면 비동기 처리에서 발생한 에러 (rejected 상태),

      then 메서드 내부에서 발생한 에러까지 모두 캐치 가능

    - 가독성 좋고 명확함

45.5 프로미스 체이닝

  - 프로미스 체이닝: then, catch, finally 프로미스 후속 처리 메서드는 언제나 프로미스를 반환하므로

    연속적으로 호출 가능 (콜백 함수가 반환한 프로미스 반환)

  - 콜백 헬 문제 해결

    - 하지만 콜백 패턴은 가독성이 좋지 않음

    - ES8 async/await를 사용하면 프로미스의 후속 처리 메서드 없이 마치 동기 처리하는 것처럼 구현 가능

      (프로미스 기반으로 동작)

45.6 프로미스의 정적 메서드

  - Promise.resolve / Promise.reject 메서드

    - 이미 존재하는 값을 래핑하여 프로미스를 생성하기 위해 사용

    - Promise.resolve 메서드: 인수로 전달받은 값을 resolve하는 프로미스 생성

    - Promise.reject 메서드: 인수로 전달받은 값을 reject하는 프로미스 생성

  - Promise.all 메서드

    - 여러 개의 비동기 처리를 모두 병렬로 처리할 때 사용

    - 프로미스를 요소로 갖는 배열 등의 이터러블을 인수로 전달받음

    - 전달받은 모든 프로미스가 fulfilled 상태가 되면 모든 처리 결과를 배열에 저장해 새로운 프로미스 반환

      - 첫 번째 프로미스가 가장 나중에 fulfilled 상태가 되어도 처리 순서 보장해서 배열에 담아 반환

    - 프로미스 하나라도 rejected 상태 되면 즉시 종료 (catch 있으면 에러 반환)

  - Promise.race 메서드

    - 프로미스를 요소로 갖는 배열 등의 이터러블을 인수로 전달받음

    - 모든 프로미스가 fulfilled 상태가 되는 것을 기다리는 것이 아니라

      가장 먼저 fulfilled 상태가 된 프로미스의 처리 결과를 resolve하는 새로운 프로미스 반환

    - 프로미스가 하나라도 rejected 상태 되면 즉시 종료 (catch 있으면 에러 반환)

  - Promise.allSettled 메서드 (ES11)

    - 프로미스를 요소로 갖는 배열 등의 이터러블을 인수로 전달받음

    - 전달받은 프로미스가 모두 settled 상태 (비동기 처리 수행된 상태, fulfilled 또는 rejected)가 되면

      처리 결과를 배열로 반환

    - 인수로 전달받은 모든 프로미스들의 처리 결과가 모두 담겨 있음

45.7 마이크로태스크 큐

  - 프로미스 후속 처리 메서드의 콜백 함수는 태스크 큐가 아니라 마이크로태스크 큐 (Job Queue)에 저장됨

  - 태스크 큐; 비동기 함수의 콜백 함수나 이벤트 핸들러가 태스크 큐에 일시 저장됨

  - 마이크로태스크 큐; 프로미스의 후속 처리 메서드의 콜백 함수가 일시 저장됨

  - 마이크로태스크 큐는 태스크 큐보다 우선순위가 높음

45.8 fetch

  - fetch 함수 (Web API)

    - HTTP 요청 전송 기능 제공하는 클라이언트 사이드 Web API

    - 프로미스 지원, 비동기 처리 유용

    - HTTP 요청 전송할 URL, HTTP 요청 메서드, HTTP 요청 헤더, 페이로드 등을 설정한 객체 전달

    - HTTP 응답을 나타내는 Response 객체를 래핑한 Promise 객체 반환

      - Response.prototype.json 메서드: Response 객체에서 HTTP response.body를 취득하여 역직렬화

  - GET 요청

  - POST 요청

  - PATCH 요청

  - DELETE 요청

반응형

댓글