ES6에서 비동기 처리를 위해 도입된 Promise는 전통적인 콜백 패턴의 단점을 보완하며 비동기 처리 시점을 명확하게 표현할 수 있다는 장점이 있다.
비동기 처리를 위한 콜백 패턴의 단점
콜백 헬
비동기 함수를 호출하면 함수 내부의 비동기로 동작하는 코드가 완료되지 않아도 즉시 종료된다. 즉, 비동기 함수 내부의 비동기로 동작하는 코드는 비동기 함수가 종료된 이후에 완료되므로 처리 결과를 외부로 반환하거나 상위 스코프 변수에 할당하면 기대한 대로 동작하지 않는다.
비동기 함수가 호출되면 함수 코드를 평가하는 과정에서 함수의 실행 컨텍스트가 생성되고 실행 컨텍스트 스택(콜 스택)에 푸시된다.
비동기 함수가 종료하면 함수 실행 컨텍스트가 콜스택에서 팝된다.
이벤트 핸들러는 이벤트가 발생하면 일단 태스크 큐에 저장되어 대기하다가, 콜 스택이 비면 이벤트 루프에 의해 콜 스택으로 푸시되어 실행된다.
45장. 프로미스
비동기 처리를 위한 콜백 패턴의 단점
콜백 헬
에러 처리의 한계
setTimeout
이 호출되면 함수의 실행 컨텍스트가 생성되어 콜 스택에 푸시되어 실행되는데 비동기 함수이므로 즉시 종료되어 콜 스택에서 제거된다.setTimeout
함수는 이미 콜 스택에서 제거되었으므로 콜백 함수의 호출자가setTimeout
함수가 아니다. 에러는 호출자 방향으로 전파되므로catch
에서 잡히지 않는다.프로미스의 생성
Promise
생성자 함수를new
연산자와 함께 호출하면Promise
객체를 생성한다.Promise
생성자 함수는resolve
와reject
함수를 인수로 전달받는 콜백 함수를 인수로 받는다.프로미스의 후속 처리 메서드
Promise.prototype.then
then
메서드는 언제나 프로미스를 반환한다.Promise.prototype.catch
catch
메서드는 한 개의 콜백 함수를 인수로 전달받는다. 프로미스가 rejected 상태인 경우만 호출된다.Promise.prototype.finally
프로미스의 에러 처리
프로미스 체이닝
then
,catch
,finally
후속 처리 메서드는 콜백 함수가 반환한 프로미스를 반환하므로 연속적으로 호출할 수 있는데 이를 프로미스 체이닝이라 한다.async/await
을 통해 해결할 수 있다.프로미스의 정적 메서드
Promise
는 객체이므로 메서드를 가질 수 있다.Promise.resolve / Promise.reject
Promise.all
Promise.all
메서드는 인수로 전달받은 배열의 모든 프로미스가 모두fulfilled
상태가 되면 종료한다.Promise.all
메서드가 종료하는 데 걸리는 시간은 가장 늦게fulfilled
상태가 되는 프로미스의 처리 시간보다 조금 더 길다.fulfilled
상태가 되면 resolve된 처리 결과를 모두 배열에 저장해 새로운 프로미스를 반환한다. 처리 수순서의 보장Promise.race
fulfilled
상태가 된 프로미스의 처리 결과를 resolve하는 새로운 프로미스를 반환하는 메서드Promise.allSettled
settled(fulfilled or rejected)
상태가 되면 처리 결과를 배열로 반환한다.fulfilled
: status && value(처리 결과)rejected
: status && reason마이크로태스크 큐
fetch