轮询多个端点时,Redux Saga的收益非常缓慢

时间:2019-04-23 20:27:41

标签: redux-saga

我正在使用redux-saga同时轮询两个API,并且希望通过race来控制两个轮询,并且可以同时停止这两个轮询:

function* root() {
    yield all([
      call(startSimulation),
      takeEvery(RESTART_SIMULATION, stopAndStartSimulation),
      takeEvery(STOP_SIMULATION, haltSimulation),
  ])


export function* startPolling(vin: string) {
  yield all([call(pollEventsSagaWorker), call(pollStatusSagaWorker, vin)])
}

export function* initiateSimulation() {
  const vin = yield select(vinSelector)
  yield call(startPolling, vin)
}

export function* haltSimulation() {
  const runningSimulation = yield select(simulationsDataSelector)
  if (runningSimulation) {
    yield put(deleteSimulation(runningSimulation.id))
  }
}

export function* startSimulation() {
  while (true) {
    yield take(INIT_SIMULATION)
    yield race([call(initiateSimulation), take(STOP_SIMULATION)])
  }
}

export function* stopAndStartSimulation() {
  yield put(stopSimulation())
  // do some other stuff
}

stopSimulation()是动作创建者(类型为STOP_SIMULATION)。

以下是轮询传奇的一个示例:

export function* pollEventsSagaWorker() {
  while (true) {
    try {
      yield put(fetchEvents())
      yield delay(EVENT_POLL_INTERVAL)
    } catch (err) {
      console.error('polling failed', err)
    }
  }
}

问题是,当我打电话给STOP_SIMULATION时,需要花几秒钟的时间才能继续进行(同时UI也被卡住了)-可能是什么原因?

1 个答案:

答案 0 :(得分:1)

我在redux-saga文档中找到了一些模式,可以通过使用cancel而不是race来解决这种情况。使用它将:

  

取消当前的效果,该效果在以下时间被阻止   取消。

我添加了一个示例(与您的代码相同),可以在触发STOP_SIMULATION动作后立即触发取消效果。

// THE CONTROL LOOP
export function* mainSaga() {
    while (yield take(INIT_SIMULATION)) {
        // starts the task in the background
        const task = yield fork(pollEventsSagaWorker);

        // wait for the user stop action
        yield take(STOP_SIMULATION);
        // user clicked stop.
        // cancel the polling by causing the forked saga to enter its finally block
        yield cancel(task);
    }
}

这将导致pollEventsSagaWorker将取消信息向下传播到所有子任务。

  

如果被叫方仍在等待中,而主叫方决定取消   该操作会触发一种信号,该信号向下传播到   被调用方(可能还会执行被调用方调用的任何深层操作   本身)。所有待处理的操作都将被取消。

export function* pollEventsSagaWorker() {
    try {
        while (true) {
            yield put(fetchEvents());
            yield delay(EVENT_POLL_INTERVAL);
        }
    } finally {
        if (yield cancelled()) {
            console.error('polling stopped');
        }
    }
}

检查此推荐人task-cancellation