프린세스 다이어리

프로미스 후속 처리 메서드(resolve, reject, all, race, allSettled) 정리 본문

FE

프로미스 후속 처리 메서드(resolve, reject, all, race, allSettled) 정리

개발공주 2022. 1. 29. 23:35
728x90

RxJS 공부를 시작하다가, 기존 자바스크립트에서 어떤 방식으로 프로미스를 처리했는지 다시 공부하고 싶어 예전에 공부한 내용을 정비하여 끌올해보았다. 내용 출처: 모던자바스크립트 Deep Dive 45장

 

1. Promise.resolve / Promise.reject

📌 Promise.resolve / Promise.reject 는 이미 존재하는 값을 래핑하여 프로미스를 생성함

 

인수로 전달한 배열을 resolve하는 프로미스를 생성

const resolvedPromise = Promise.resolve([1,2,3])
resolvedPromise.then(console.log) // [1,2,3]

const resolvedPromise = new Promise(resolve => resolve([1,2,3]))
resolvedPromise.then(console.log) // [1,2,3]

→ 위 아래 코드가 동일하게 동작함.


인수로 전달한 에러 객체를 reject하는 프로미스를 생성

const rejectedPromise = Promise.reject(new Error('Error!'))
rejectedPromise.catch(console.log) // Error: Error!

const rejectedPromise = new Promise((_, reject) => reject(new Error('Errorrrrr!!!')))
rejectedPromise.catch(console.log) // Error: Errorrrrr!!!

→ 위 아래 코드가 동일하게 동작함

 

2. Promise.all

📌 Promise.all은 여러 개의 비동기 처리를 한꺼번에 병렬처리할 때 사용함

 

여러 개의 비동기 처리를 순차적으로 처리할 때

const requestData1 = () => new Promise(resolve => setTimeout(() => resolve(1), 3000))
const requestData2 = () => new Promise(resolve => setTimeout(() => resolve(2), 2000))
const requestData3 = () => new Promise(resolve => setTimeout(() => resolve(3), 1000))

const res = []
requestData1()
  .then(data => {
    res.push(data)
    return requestData2()
})
  .then(data => {
    res.push(data)
    return requestData3()
})
  .then(data => {
    res.push(data)
    console.log(res) // [ 1, 2, 3 ] => 6초
})
  .catch((err) => console.log(err))

→ 첫 번째 비동기 처리에 3초, 두 번째에 2초, 세 번째에 1초 걸려서 총 6초 이상 소요

→ 서로 의존하지 않고 개별적으로 수행되는 것. 후속 처리가 아님. 순차적으로 처리할 필요 없음

 


여러 개의 비동기 처리를 병렬적으로 처리할 때

const requestData1 = () => new Promise(resolve => setTimeout(() => resolve(1), 3000))
const requestData2 = () => new Promise(resolve => setTimeout(() => resolve(2), 2000))
const requestData3 = () => new Promise(resolve => setTimeout(() => resolve(3), 1000))

Promise.all([requestData1(), requestData2(), requestData3()])
  .then(data => console.log(data)) // [ 1, 2, 3 ] => 3초
  .catch(err => console.log(err))

→ 가장 늦게 fulfilled 상태가 되는 첫 번째 프로미스의 처리 시간인 3초 가량 걸림

→ 모든 프로미스가 fulfilled 상태가 되면 모든 처리 결과를 배열에 저장해 새로운 프로미스 반환.

→ 인수로 전달받은 배열의 프로미스가 하나라도 rejected되면 즉시 에러 띄우고 종료


Promise.all 쓰는 예제

const promiseAll = url => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.open('GET', url)
    xhr.send()
    
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(JSON.parse(xhr.response))
      } else {
        reject(new Error(xhr.status))
      }
    }
  })
}

const githubIds = ['jeresig', 'ahejlsberg', 'ungmo2']

// 순차적으로 실행될 필요가 없는 로직.
Promise.all(githubIds.map(id => promiseAll(`https://api.github.com/users/${id}`)))
  .then(users => users.map(user => user.name))
  .then(name => console.log(name)) // [ 'John Resig', 'Anders Hejlsberg', 'Ungmo Lee' ]
  .catch(err => console.log(err))

→ 깃헙 아이디로 깃헙 사용자 이름을 따는 비동기 처리를 순차적으로 처리될 필요가 없음.

 

3. Promise.race

📌 Promise.race도 프로미스를 요소로 갖는 배열 등의 이터러블을 인수로 전달받음. 가장 먼저 fulfilled된 프로미스의 처리 결과만 resolve함

 

const requestData1 = () => new Promise(resolve => setTimeout(() => resolve(1), 3000))
const requestData2 = () => new Promise(resolve => setTimeout(() => resolve(2), 2000))
const requestData3 = () => new Promise(resolve => setTimeout(() => resolve(3), 1000))

Promise.race([requestData1(), requestData2(), requestData3()])
  .then(res => console.log(res)) // 3
  .catch(err => console.log(err))

→ 다 fulilled 상태가 되기를 기다리는 게 아니라 하나만 fulfilled 되면 종료

→ 하나라도 reject되면 에러 띄우고 종료 (Promise.all이랑 같음)

 

4. Promise.allSettled

📌 Promise.allSettled도 프로미스를 요소로 갖는 배열 등의 이터러블을 인수로 받음. 그리고 각각의 비동기 처리가 settled된 상태(fulfilled 또는 rejected)를 배열로 반환함

 

Promise.allSettled([
  new Promise(resolve => setTimeout(() => resolve(1), 2000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('Error!!!')), 1000))
]).then(data => console.log(data))

// [
//   { status: 'fulfilled', value: 1 },
//   { status: 'rejected', reason: Error: 'Error!!!' }
// ]

→ 각각의 프로미스의 처리 결과가 객체로 나타남.

→ fulfilled 상태인 경우 비동기 처리 상태를 나타내는 status 프로퍼티와 처리 결과를 나타내는 value 프로퍼티 가짐

→ rejected 상태인 경우 비동기 처리 상태를 나타내는 status 프로퍼티와 에러를 나타내는 reason 프로퍼티 가짐

728x90
Comments