在redux-saga中采取顺序?

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

我有一个基本的传奇,看起来像这样:

const mySaga = function* () {
    yield takeEvery("SOME_ACTION_REQUEST", function* (action) {

        const result = yield call(makeApiCall, action.payload); 
        yield put({
            type: "SOME_ACTION_SUCCESS", 
            payload: result
        }); 

    });  
}

现在我遇到的问题是,如果我同时调度了两个"SOME_ACTION_REQUEST",那么我有一个redux调用堆栈的情况:

SOME_ACTION_REQUEST
SOME_ACTION_REQUEST
SOME_ACTION_SUCCESS
SOME_ACTION_SUCCESS

而这正在削弱我的减速机中的逻辑。

我想要的是,每个请求都要运行,但是它要等待前一个请求在启动之前完成。

即。所以它看起来像:

SOME_ACTION_REQUEST
SOME_ACTION_SUCCESS
SOME_ACTION_REQUEST
SOME_ACTION_SUCCESS

我怎么做到这一点?

redux-saga
2个回答
0
投票

actionChannel效应可用于实现这一目标。

见:https://redux-saga.js.org/docs/api/#actionchannelpattern-buffer

const mySaga = function* () {
    const channel = yield actionChannel("SOME_ACTION_REQUEST"); 
    while (true) {
        const action = take(channel); 
        const result = yield call(makeApiCall, action.payload); 
        yield put({
            type: "SOME_ACTION_SUCCESS", 
            payload: result
        }); 
    }
}

说明:

我的理解是actionChannel效果只是将匹配该模式的所有传入请求路由到队列中。

take效应会让它们脱落。

将它全部放在while(true)循环中意味着一次一个地弹出一个动作,并且它们需要等待在下一个动作被调用之前解决所有其他事情(API调用)。

关于这种模式需要注意的一点是,在redux-dev-tools中,redux堆栈仍然看起来像:

SOME_ACTION_REQUEST
SOME_ACTION_REQUEST
SOME_ACTION_SUCCESS
SOME_ACTION_SUCCESS

因为请求会立即添加到频道并保持不活动状态,直到它们被弹出为止。


0
投票

只需两个分叉任务即可实现此目的。就像一个乒乓消息系统。

对于takeEvery,始终为收到的每个操作创建一个新的分叉任务。

像这样的东西:

function* ping() {
  while (true) {
    const { payload } = yield take("SOME_ACTION_REQUEST");
    yield put({
      type: "DO_REQUEST", 
      payload
    });
    yield take("SOME_ACTION_SUCCESS");
  }
}

function* pong() {
  while (true) {
    const { payload } = yield take("DO_REQUEST");
    const result = yield call(makeApiCall, payload); 
    yield put({
      type: "SOME_ACTION_SUCCESS", 
      payload: result
    }); 
  }
}

function* rootSaga() {
  yield all([
    fork(ping),
    fork(pong),
  ]);
}
© www.soinside.com 2019 - 2024. All rights reserved.