Promise 정적 방법의 사용 방법 요약

비동기 처리 정보


JavaScript에서 시간이 걸리는 처리는 기본적으로 결과를 기다리지 않고 후속 처리를 먼저 하는 비막힘 처리입니다.
이러한 처리는 비동기 처리라고 불리며 콜백 함수를 사용하고Promise 대상을 사용하며async/await를 사용하는 등 처리 방법이 달라졌다.
필자는 async/await를 자주 사용한다.그러나 예를 들어 여러 테이블에 쓰기, 여러 외부 API로부터 데이터를 얻고 연결하는 등 비동기 처리를 병행하려는 경우 등이 존재하며, 이 경우 async/await를 하나하나 진행하면 자바스크립트의 특성을 활용할 수 없다예외적인 처리 등은 지루해질 수 있다.
이번에는 이 문제들을 해결할 수 있는 정적 방법Promise을 총결하였다.

차리다


먼저 Promise의 샘플을 반환하는 함수를 만듭니다.


// msを受け取る
const sleep = (ms: number) => {
  // Promiseコンストラクタは一つの型引数と一つのexecutor関数を取ります。
  // excutor関数では、第一引数にfullfilledしたときのコールバック関数を第二引数にrejectedされたときのコールバック関数を受けます。慣例的に、resolve, rejectと命名します。
  return new Promise<string>((resolve, reject) => {
    // rejectされた時の動作を検証したいので、便宜的に追加しました。
    if (ms > 2000) {
      reject('Too Long to wait')
    }
    setTimeout(() => {resolve('success!!')}, ms)
  })
}

console.시간으로 처리 시간을 측정하다

console.time부터 측정하고 console.timeEnd()에서 측정을 끝냅니다.자세한 사용 방법은여기.
console.time()
sleep(1000).then(data => {
  console.log(data)
  console.timeEnd()
})

Promise.all


모든 결과가 fullfiled될 때까지 진열로promise를 받아들입니다.
리젝트에 의해 그 시간에 흐르면 .catch.

다 풀필러에 걸린 상황.


console.time()
const p1 = sleep(1000)
const p2 = sleep(1500)
const p3 = sleep(2000)

const promiseAll = Promise.all([p1, p2, p3])

promiseAll.then(data => {
  console.log(data)
}).catch(err => {
  console.log(`err: ${err}`)
}).finally(() => {
  console.timeEnd()
})
최장p3이 끝날 때까지 기다려야 하므로 끝날 때까지 2000ms 정도 소요됩니다.
$ node dist/index.js
[ 'success!!', 'success!!', 'success!!' ]
default: 2.018s

부분 리ject

p3 Promise를 작성하는 동안 Reject가 수행됩니다.
리퀘스트에 의해 .catch 이동합니다.
console.time()
const p1 = sleep(1000)
const p2 = sleep(1500)
const p3 = sleep(3000) // rejectされる

const promiseAll = Promise.all([p1, p2, p3])

promiseAll.then(data => {
  console.log(data)
}).catch(err => {
  console.log(`err: ${err}`) // こちらに流れる
}).finally(() => {
  console.timeEnd()
})
$ node dist/index.js
err: Too Long to wait
default: 6.508ms

Promise.race


첫 번째 setteled 결과Promise.race의 Promise는 settled에 의해

다 풀필러에 걸린 상황.


console.time()
const p1 = sleep(1000)
const p2 = sleep(1500)
const p3 = sleep(2000) 

const promiseRace = Promise.race([p1, p2, p3])

promiseRace.then(data => {
  console.log(data)
}).catch(err => {
  console.log(`err: ${err}`)
}).finally(() => {
  console.timeEnd()
})
p1이 해결되었을 때Promise.race의Promise가 해결되었고 전체 처리는 약 1초 만에 끝났다.
$ node dist/index.js
success!!
default: 1.008s

부분 리ject


console.time()
const p1 = sleep(1000)
const p2 = sleep(1500)
const p3 = sleep(3000) // rejectされる

const promiseRace = Promise.race([p1, p2, p3])

promiseRace.then(data => {
  console.log(data)
}).catch(err => {
  console.log(`err: ${err}`)
}).finally(() => {
  console.timeEnd()
})
$ node dist/index.js
err: Too Long to wait
default: 7.745ms

Promise.allSettled

Promise.all에서 Reject를 처리할 때 다른 처리를 기다리지 않고 Promise.all 되돌아오는 Promise는 settled이지만 실패는 먼저 실패하고 다른 처리가 끝날 때까지 기다릴 수 있습니다.이때 사용Promise.allSettled.

다 풀필러에 걸린 상황.


console.time()
const p1 = sleep(1000)
const p2 = sleep(1500)
const p3 = sleep(2000)

const promiseRace = Promise.allSettled([p1, p2, p3])

promiseRace.then(data => {
  console.log(data)
}).catch(err => {
  console.log(`err: ${err}`)
}).finally(() => {
  console.timeEnd()
})
처리 시간 등은 Promise.all와 같고 다음과 같다.
$ node dist/index.js
[
  { status: 'fulfilled', value: 'success!!' },
  { status: 'fulfilled', value: 'success!!' },
  { status: 'fulfilled', value: 'success!!' }
]
default: 2.026s

부분 리ject


console.time()
const p1 = sleep(1000)
const p2 = sleep(1500)
const p3 = sleep(3000) // rejectされる

const promiseRace = Promise.allSettled([p1, p2, p3])

promiseRace.then(data => {
  console.log(data)
}).catch(err => {
  console.log(`err: ${err}`)
}).finally(() => {
  console.timeEnd()
})
p3는 즉시 실패하고 대기p2후 약 1.5초 만에 처리가 종료됩니다.
$ node dist/index.js
[
  { status: 'fulfilled', value: 'success!!' },
  { status: 'fulfilled', value: 'success!!' },
  { status: 'rejected', reason: 'Too Long to wait' }
]
default: 1.524s

좋은 웹페이지 즐겨찾기