メインコンテンツにスキップ

複数の効果間のレースの開始

ときに、複数のタスクを並列で開始しても、すべてを待機ではなく、解決(または拒否)された最初のもの(ウィナー)を取得する必要がある場合があります。レース効果は、複数の効果間でレースを開始する方法を提供します。

次のサンプルは、リモートフェッチリクエストを開始し、応答を 1 秒以内に制約するタスクを示しています。

import { race, call, put, delay } from 'redux-saga/effects'

function* fetchPostsWithTimeout() {
const {posts, timeout} = yield race({
posts: call(fetchApi, '/posts'),
timeout: delay(1000)
})

if (posts)
yield put({type: 'POSTS_RECEIVED', posts})
else
yield put({type: 'TIMEOUT_ERROR'})
}

他に便利なレースの機能として、負け効果が自動的にキャンセルされるというものがあります。たとえば、2 つの UI ボタンがあるとします。

  • 1 つ目は、無限ループ while (true) でバックグラウンドでタスクを開始します(たとえば、x 秒ごとにサーバーとデータを同期するなど)。

  • バックグラウンドタスクが開始されると、2 つ目のボタンを有効にしてタスクをキャンセルします。

import { race, take, call } from 'redux-saga/effects'

function* backgroundTask() {
while (true) { ... }
}

function* watchStartBackgroundTask() {
while (true) {
yield take('START_BACKGROUND_TASK')
yield race({
task: call(backgroundTask),
cancel: take('CANCEL_TASK')
})
}
}

CANCEL_TASK アクションがディスパッチされると、レース効果は自動的にbackgroundTask をキャンセルのエラーが発生して中に投げ出されてキャンセルします。