跳至主要内容

在多个效果之间开始竞速

有时我们会并行启动多个任务,但我们不想等待所有任务完成,我们只需要获得获胜者:第一个完成(或拒绝)的任务。race 效果提供了一种在多个效果之间触发竞赛的方法。

以下示例展示了一个触发远程获取请求的任务,并将响应限制在 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'})
}

race 的另一个有用功能是它会自动取消失败的效果。例如,假设我们有 2 个 UI 按钮

  • 第一个在后台启动一个在无限循环 while (true) 中运行的任务(例如,每隔 x 秒与服务器同步一些数据)。

  • 后台任务启动后,我们将启用第二个按钮,该按钮将取消该任务

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 操作,race 效果将通过在其中抛出取消错误来自动取消 backgroundTask