轮询多个端点时,Redux Saga的产生速度非常慢

问题描述 投票:1回答:1

我正在使用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也会被卡住) - 原因可能是什么?

redux-saga
1个回答
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');
        }
    }
}

查看此参考qazxsw poi

© www.soinside.com 2019 - 2024. All rights reserved.