Promise

컨스탄트·2022년 1월 24일
0

모던자바스크립트

목록 보기
13/13
post-thumbnail

프로미스의 생성

Promise 생성자 함수는 비동기 처리를 수행할 콜백함수를 인수로 전달받는데 이 콜백함수는 resolve와 reject함수 이다.

비동기 함수인 promiseGet은 함수내부에서 프로미스를 생성하고 반환한다.

프로미스는 다음과 같이 현재 비동기 처리가 어떻게 진행되고 있는지를 나타내는 상태정보를 갖는다.

pending => 비동기 처리가 아직 수행되지 않은상태
(프로미스가 생성된 직후의 상태)

fulfilled => 비동기 처리가 성공적으로 수행된 상태
(resolve 함수 호출)

rejected => 비동기 처리가 실패한 상태
(reject 함수 호출)

비동기 처리가 성공하면 resolve 함수를 호출해 프로미스를 fulfilled 상태로 변경하고 실패하면 reject 함수를 호출해 프로미스를 rejected 상태로 변경한다.

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

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

프로미스의 비동기 처리 상태가 변화하면 이에 따른 후속 처리를 해야 한다. 후속 메서드로는 then, catch, finally를 제공한다.

프로미스의 비동기 처리 상태가 변화하면 후속 처리 메서드에 인수로 전달한 콜백함수가 선택적으로 호출된다.

모든 후속처리 메서드는 프로미스를 반환하며, 비동기로 동작
한다.

then

then 메서드는 두개의 콜백함수를 인수로 전달받는다.

첫번째 콜백함수는 프로미스가 fulfilled 상택 되면 호출된다. 이때 콜백함수는 프로미스의 비동기 처리결과를 인수로 전달받는다.

두번째 콜백함수는 프로미스가 rejected 상태가 되면 호출된다. 이때 콜백함수는 프로미스의 에러를 인수로 전달 받는다.

만약 then 메서드의 콜백함수가 프로미스를 반환하면 그 프로미스를 그대로 반환하고, 프로미스가 아닌 값을 반환하면 그 값을 암묵적으로 resolve 또는 reject하여 프로미스를 생성해 반환

catch

catch 메서드는 한개의 콜백함수를 인수로 전달받는다. 프로미스가 rejected 상태인 경우만 호출된다.
then 메서드와 마찬가지로 언제나 프로미스를 반환한다.

finally

한개의 콜백 함수를 인수로 전달받는다. 상태와 상관없이 무조건 한번 호출 된다. 언제나 프로미스를 반환한다.

프로미스 체이닝

비동기 처리를 위한 콜백 패턴은 콜백 헬이 발생하는 문제가 있다. 이는 then,catch,finally를 통해 해결 가능


then, catch, finally는 언제나 프로미스를 반환하기 때문에 연속 호출이 가능하다. 이를 프로미스 체이닝이라 한다.

다만 프로미스도 콜백패턴을 사용하므로 가독성이 좋지 않다.
이 문제는 ES8에서 도입된 async/await를 통해 해결가능하다.

프로미스 정적메서드

Promise.resolve / reject

Promise.all

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

이런 코드가 있다 해보자. 이 코드는 총 3초 -> 2초 ->1초로 순차적으로 진행이되어 총 6초가 걸릴 것이다.

그런데 위 예제의 경우 세 개의 비동기 처리는 서로 의존하지 않고 개별적으로 수행된다. 즉 앞선 비동기 처리 결과를 다음 비동기 처리가 사용하지 않는다. 따라서 위 예제의 경우 순차적으로 처리할 필요가 없다.

그럼 이것들을 병렬로 처리해보자.

3개의 promise가 모두 fulfilled 상태가 되면 resolve 된 처리결과를 모두 배열에 저장해 새로운 프로미스를 반환한다.

이때 첫번째 프로미스가 가장 나중에 fulfilled 상태가 되어도
Promise.all 메서드는 첫번째 프로미스가 resolve한 처리결과부터 차례대로 배열에 저장해 그 배열을 resolve하는 새로운 프로미스를 반환한다.

promise.all 메서드는 인수로 전달받은 배열의 프로미스가 하나라도 rejected 상태가 되면 나머지 프로미스가 fulfilled 상태가 되는 것을 기다리지 않고 즉시 종료한다.

Promise.race

이 메서드는 Promise.all 메서드와 동일하게 프로미스를 요소로 갖는 배열 등의 이터러블을 인수로 전달받는다.

all 메서드처럼 모든 프로미스가 fulfilled 상태가 되는 것을 기다리는 것이 아니라 가장 먼저 fulfilled 상태가 된 프로미스의 처리 결과를 resolve 하는 새로운 프로미스를 반환한다.

Promise.allSettled

프로미스를 요소로 갖는 배열 등의 이터러블을 인수로 전달받는다. 그리고 전달받은 프로미스가 모두 settled 상태 (비동기 처리가 수행된 상태, 즉 fulfilled 또는 rejected상태) 가 되면 처리 결과를 배열로 반환한다.

마이크로태스크 큐

어떻게 출력이 될까?

2 -> 3 -> 1의 순서로 출력이 된다. 그 이유는 프로미스의 후속처리 메서드의 콜백함수는 태스크 큐가 아니라 마이크로태스크 큐에 저장되기 때문이다.

마이크로태스크 큐는 태스크 큐와는 별도의 큐다. 마이크로태스크 큐에는 프로미스의 후속 처리 메서드의 콜백함수가 일시 저장된다. 그 외의 비동기 함수의 콜백함수나 이벤트 핸들러는 테스크 큐에 일시 저장된다.

콜백함수나 이벤트 핸들러를 일시 저장한다는 점에서 태스크 큐와 동일하지만 마이크로태스크 큐는 태스크큐보다 우선순위가 놓다.

profile
꾸준히 개발을 즐기는 사람입니다

0개의 댓글

관련 채용 정보