[JS] Promise (2)

Promise.all

let promise = Promise.all([...promises...]);

promise.all은 요소 전체가 promise인 배열을 받고 새로운 promise를 반환한다.
배열 안 promise의 결과값을 담은 배열이 새로운 promise의 result가 된다.

아래 Promise.all은 3초 후 처리되고, 반환되는 promise의 result[1, 2, 3]이 된다.

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);

Promise 전체가 처리되면 1, 2, 3이 반환된다. 배열 result의 요소 순서는 Promise.all에 전달되는 promise 순서와 상응한다. Promise.all의 첫 번째 promise는 가장 늦게 이행되더라도 처리 결과는 배열의 첫 번째 요소에 저장된다.

Promise.all([
 new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),
 new Promise((resolve, reject) => setTimeout(() => reject(new Error("error")), 2000)),
 new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000)),
]).catch(alert);

Promise.all에 전달되는 promise 중 하나라도 거부되면 Promise.all이 반환하는 promise는 에러와 함께 바로 거부된다. 2초 후 2번째 promise가 거부되면서 Promise.all 전체가 거부되고, .catch가 실행된다. 거부 에러는 Promise.all 전체의 결과가 된다.


Promise.allSettled

Promise.all은 promise가 하나라도 거절되면 전체를 거절한다. 반면, Promise.allSettled는 모든 promise가 처리될 때까지 기다린다. 반환되는 배열은 다음과 같은 요소를 갖는다.

  • 응답이 성공한 경우 : {status: "fulfilled", value: result}
  • 에러가 발생한 경우 : {status: "rejected", reason: error}

fetch를 사용해 여러 사람의 정보를 가져오고 있다고 가정할 때, 여러 요청 중 하나가 실패해도 다른 요청 결과는 여전히 있어야 한다. 이러한 경우 Promise.allSettled를 사용한다.

let urls = [
  'https://api.github.com/users/iliakan',
  'https://api.github.com/users/remy',
  'https://no-such-url'
];

Promise.allSettled(urls.map(url => fetch(url)))
  .then(results => {
    results.forEach((result, num) => {
      if (result.status == "fulfilled") {
        alert(`${urls[num]}: ${result.value.status}`);
      }
      if (result.status == "rejected") {
        alert(`${urls[num]}: ${result.reason}`);
      }
    });
  });

응답 results 결과는

[
 {status: 'fulfilled', value: ...응답...},
 {status: 'fulfilled', value: ...응답...},
 {status: 'rejected', value: ...에러...}
]

Promise.allSettled를 사용하면 이처럼 각 promise 상태와 값 또는 에러를 받을 수 있다.


Promise.race

Promise.race는 가장 먼저 처리되는 promise의 결과(혹은 에러)를 반환한다.

Promise.race([
 new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),
 new Promise((resolve, reject) => setTimeout(() => reject(new Error("error")), 2000)),
 new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
]).then(alert);

위 코드에서 첫 번째 promise가 가장 빨리 처리상태가 되기 때문에 첫 번째 promise의 결과가 result 값이 된다. 가장 먼저 처리된 promise 이외의 결과 또는 에러는 무시된다.


Promise.resolve / Promise.reject

Promise.resolvePromise.rejectasync/await 문법이 생긴 후로 사용할 이유가 거의 없어졌다.

Promise.resolve

let promise = new Promise(resolve => resolve(value));

Promise.resolve(value)는 결과값이 value인 이행 상태 promise를 생성한다.

Promise.reject

let promise = new Promise((resolve, reject) => reject(error));

Promise.reject(error)는 결과값이 error인 거부 상태 promise를 생성한다.
실무에서 이 method를 쓸 일은 거의.. 없다고 한다.

참고 출처 : https://ko.javascript.info/async

좋은 웹페이지 즐겨찾기