我正在尝试添加redux saga函数,但无法正确链接
const randomDelay = () => parseInt(Math.random() * 500)
const a = function*() {
yield spawn(b)
yield call(c)
}
const b = function*() {
yield delay(randomDelay())
}
const c = function*() {
yield delay(randomDelay())
}
const d = function*() {}
a
,它将产生b
并呼叫c
。 c
完成后,我希望a
变得畅通无阻且完整。b
和c
都填写完后,我想打电话给d
据我所知,没有办法做到这一点。 all
或fork
将阻止a
现在要解决此问题,我先调用了c
,然后生成了b
和d
的组合,但这意味着b
和c
可以不能同时运行。
答案 0 :(得分:0)
为此,您需要一个单独的信令机制。我会为此使用channel
。
a
首先创建一个频道a
产生dScheduler
通过通道a
将通道作为参数传递给b
b
对结尾的频道进行put
a
在结束时对频道进行put
(c
完成后)dScheduler
在频道上执行两个take
,然后调用d
代码如下所示:
import { delay, channel } from "redux-saga";
import { spawn, call, put, take } from "redux-saga/effects";
const randomDelay = () => parseInt(Math.random() * 500);
const B_OR_C_COMPLETED = "B_OR_C_COMPLETED";
export const a = function*() {
const bcCompletedChannel = channel();
yield spawn(dScheduler, bcCompletedChannel);
yield spawn(b, bcCompletedChannel);
yield call(c);
yield put(bcCompletedChannel, B_OR_C_COMPLETED);
};
const b = function*(bcCompletedChannel) {
yield delay(randomDelay());
yield put(bcCompletedChannel, B_OR_C_COMPLETED);
};
const c = function*() {
yield delay(randomDelay());
};
const dScheduler = function*(bcCompletedChannel) {
yield take(bcCompletedChannel);
yield take(bcCompletedChannel);
yield call(d);
};
const d = function*() {
};
这里是一个CodeSandbox,其中添加了控制台日志,并且延长了延迟,以便于验证行为。
Redux Saga文档的相关部分是here。具体来说,靠近底部的部分称为“使用Sagas之间的通讯渠道”。
答案 1 :(得分:0)
不如https://stackoverflow.com/a/54140525/4453205优雅。
我的答案还假设a
只是调用b
和c
(或仅执行两个任务)。
import { delay } from "redux-saga";
import { all, cancel, put, takeEvery, spawn, call } from "redux-saga/effects";
const randomDelay = () => parseInt(Math.random() * 500);
export function* startTasks() {
let completed = yield call(a);
if (completed) {
yield call(d);
}
}
const a = function*() {
let b_finished = false;
const b = function*() {
yield delay(randomDelay());
yield put({ type: "B_DONE" });
b_finished = true;
};
const c = function*() {
yield delay(randomDelay());
yield put({ type: "C_DONE" });
};
const taskB = yield spawn(b);
yield call(c);
yield cancel(taskB);
return b_finished;
};
const d = function*() {
yield delay(randomDelay());
yield put({ type: "D_DONE" });
};
export function* watchStartTasks() {
yield takeEvery("START_TASKS", startTasks);
}
export default function* rootSaga() {
yield all([watchStartTasks()]);
}