Promise 클래스의 5가지 정적 메서드, 이중 Promise.all을 가장 많이 사용한다.
let promise = Promise.all([...promises...]);
//---사용예---
Promise.all([
new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
new Promise(resolve => setTimeout(() => resolve(3), 1000)) // 3
]).then(alert); // 프라미스 전체가 처리되면 1, 2, 3이 반환됩니다. 각 프라미스는 배열을 구성하는 요소가 됩니다.
==> 배열 또는 이터러블 객체를 요소로 받아 새로운 프라미스 리턴함. (일반 값도 요소로 넘기기 가능)
Promise.all에 전달되는 프라미스 중 하나라도 거부되면 Promise.all이 반환하는 프라미스는 에러와 함께 바로 거부(REJECT)됨.
(하나라도 거부되는 순간 바로 Promise.all이 거부되므로 배열에 저장된 다른 프라미스의 결과는 완전 무시됨, 이행된 결과도 무시)
최근 스펙에 추가된 문법. Promise.all과 달리 모든 프라미스가 처리될 때까지 기다림.
여러 요청 중 하나가 실패하더라도 다른 요청 결과가 필요할때 사용하며, 각 프라미스의 상태와 값 또는 에러를 받음.
> 응답이 성공할 경우 – {status:"fulfilled", value:result}
> 에러가 발생한 경우 – {status:"rejected", reason:error}
Promise.race, Promise.all과 비슷하나, 가장 먼저 처리되는 프라미스의 결과(혹은 에러)를 반환.
문법:
let promise = Promise.race(iterable);
Promise.race([
new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),
new Promise((resolve, reject) => setTimeout(() => reject(new Error("에러 발생!")), 2000)),
new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
]).then(alert); // 1
가장 빨리 처리상태가 되는 첫번째 프라미스의 결과만 리턴되고, 나머지는 무시됨.
async/await이 생긴 후 잘 사용되지 않음.
- Promise.resolve : Promise.resolve(value)는 결괏값이 value인 이행 상태 프라미스를 생성.
- Promise.reject : Promise.reject(error)는 결괏값이 error인 거부 상태 프라미스 생성.
'프라미스화(Promisification)' : 콜백을 받는 함수 -> 프라미스 반환 함수로 바꾸는 것.
- async/await과 함께 프라미스화 해서 사용하는것 권장. But, 콜백을 완전 대체하지는 못함.
프라미스는 하나의 결과만 가질 수 있지만, 콜백은 여러번 호출할 수 있기 때문.
프라미스화는 콜백을 단 한 번 호출하는 함수에만 적용할것. 프라미스 화한 함수의 콜백은 여러 번 호출해도 두 번째부터는 무시됨.
모든 프라미스 동작은 '마이크로태스크 큐'라는 내부 Promise Job 큐에 들어가서 처리되어 프라미스 핸들링은 항상 비동기처리.
.then/catch/finally 핸들러는 항상 현재 코드가 종료되고 난 후에 호출된다.
let promise = Promise.resolve();
promise.then(() => alert("프라미스 성공!"));
alert("코드 종료"); // 얼럿 창이 가장 먼저 뜹니다.
//코드종료 알러트가 먼저 뜨고, 그 다음 프라미스 성공 알러트가 뜨게된다.
만약 .then/catch/finally 호출 이후에 실행할 코드가 있다면,
.then을 체인에 추가하여 그 안에 작성할 것.
Promise.resolve()
.then(() => alert("프라미스 성공!"))
.then(() => alert("코드 종료"));
처리되지 못한 거부 unhandledrejection
마이크로태스크 큐 끝에서 프라미스 에러가 처리되지 못할 때 발생.
이를 대비해 프라미스 체인에 .catch 추가해 에러 처리.
만약, 개발자가 .catch를 추가하지 않은 경우, 엔진은 마이크로태스크 큐가 빈 이후 unhandledrejection 이벤트를 트리거.
let promise = Promise.reject(new Error("프라미스 실패!"));
setTimeout(() => promise.catch(err => alert('잡았다!')), 1000);
// Error: 프라미스 실패!
window.addEventListener('unhandledrejection', event => alert(event.reason));
위의 경우, catch를 늦게 실행해 마이크로태스크 큐 내부 작업을 모두 완료한 후 unhandledrejection이 생성됨.
때문에, "프라미스 실패!'가 먼저 출력된 후에 '잡았다!'가 출력된다.
javascript.info - 제너레이터와 비동기 이터레이션 (0) | 2023.01.02 |
---|---|
javascript.info - 프라미스와 async, await(3) (0) | 2023.01.02 |
javascript.info - 프라미스와 async, await (0) | 2023.01.02 |
javascript.info - 10.에러 핸들링 (0) | 2023.01.01 |
javascript.info - 9.클래스 (0) | 2022.12.30 |