1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AbortControllerを使わないで遅い非同期処理のキャンセルをする方法

Posted at

はじめに

サードパーティライブラリのPromiseな関数をタイムアウトさせたい場面があり、
AbortControllerを使わずPromise.race()でシンプルに実装してみました。

Promise.race()とは?

Promise.race() は静的メソッドで、入力としてプロミスの反復可能オブジェクトを受け取り、単一の Promise を返します。この返されたプロミスは、最初に決定したプロミスの最終的な状態で決定されます。

引用元 : MDN - Promise.race()

簡単に言えば、複数のPromiseを競わせて一番非同期処理が早い結果を返して、残りの遅い処理はキャンセルするという事になります。

一番に非同期処理が終わったらrejectされている場合も返却される点に注意が必要です。

実装例

libFunctionの非同期処理が2秒以上かかる場合は、timeoutPromiseの結果が返される事で、
実質的にlibFunctionをキャンセルしています。

※ 今回はPromiseの返却値の型をstringにしていますが、それぞれ返却値に応じた型を指定すれば大丈夫です。

import libFunction from 'FOO PATH' // 非同期なライブラリ関数をインポート

async function doTask(){
  const TIMEOUT = 2000 // タイムアウト時間 (Milliseconds)
  
  // ライブラリのPromise関数をラップ
  const wrappedLibFunction = new Promise<string>(resolve =>
    libFunction().then((text) => {
       resolve(text) // ライブラリのPromise関数の結果をresolveします。
    })
  )

  // キャンセルに使うPromise処理
  const timeoutPromise = new Promise<string>(resolve =>
    setTimeout(() => resolve('2秒後に返すtimeoutの内容'), TIMEOUT),
  )

  // 完了が早い方のPromise関数が返り値になります。
  const result = await Promise.race([wrappedLibFunction, timeoutPromise])
  return result
}

まとめ

AbortControllerを使わないで遅い非同期処理のキャンセルをPromise.race()で実装しました。

AbortControllerの方が細かい設定等が可能ですが、コードも複雑になりがちなので、
重要度が低めの非同期処理のキャンセルはPromise.race()で実装しても良いかもしれません。

参考文献

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?