gpt4 book ai didi

javascript - 使用带有 take 和 delay 的 runSaga 进行测试

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:56:36 26 4
gpt4 key购买 nike

如果我有一个具有这种形式的传奇:

function * sagaWorker() {
yield put(START_ACTION)
yield take(WAIT_FOR_ACTION)
yield delay(100)
yield put(END_ACTION)
}

我可以像这样使用 runSaga 成功测试它:

step('saga passes the tests', async () => {
const channel = stdChannel()
const dispatched = []
const options = {
dispatch: action => dispatched.push(action),
getState: () => {},
channel
}
const task = runSaga(options, sagaWorker)
channel.put(WAIT_FOR_ACTION)
await task.toPromise()
expect(dispatched).to.deep.eql([START_ACTION, END_ACTION])
})

但是,如果我将延迟移到镜头前:

function * sagaWorker() {
yield put(START_ACTION)
yield delay(100)
yield take(WAIT_FOR_ACTION)
yield put(END_ACTION)
}

现在 saga 没有运行完成并超时 - 它到达了 take 但操作从未到达 channel 。

是否可以使用此表单对其进行测试?我怀疑我可以通过 calling delay 而不是直接 yield 来让它工作,但我想知道如何制作它在不这样做的情况下工作(如果可能的话)。

最佳答案

使用 yield call(() => myPromiseyDelay(500)) 不会在此处保存您。派发时仍然不会注意到“丢失”操作。

当您发布WAIT_FOR_ACTION 时,saga 在yield delay 时处于已屈服状态。这里没有 Action 队列,所以当你到达 yield take(WAIT_FOR_ACTION) 时,WAIT_FOR_ACTION Action 早已被调度,没有被任何 saga 注意到您在上面提出的逻辑(没有事件的 take 来获取操作)。

考虑设置一个 actionChannel捕捉这些未听的 Action 。在 delay 完成后,它们将在 channel 中排队等待消费。

所以,像这样:

function * sagaWorker() {
const channel = yield actionChannel(WAIT_FOR_ACTION)
yield put(START_ACTION)
yield delay(100)
yield take(channel)
yield put(END_ACTION)
}

所以把这些放在一起作为非伪代码:

const {
runSaga,
stdChannel,
effects: {
take,
put,
actionChannel,
delay
}
} = window.ReduxSaga

const WAIT_FOR_ACTION = "WAIT_FOR_ACTION";
const START_ACTION = "START_ACTION";
const END_ACTION = "END_ACTION";

(async() => {
const channel = stdChannel();
const dispatched = [];
const options = {
dispatch: action => dispatched.push(action),
getState: () => {},
channel
};
const task = runSaga(options, sagaWorker);
channel.put({
type: WAIT_FOR_ACTION
});
await task.toPromise();
console.log(dispatched);
})();

function* sagaWorker() {
const channel = yield actionChannel(WAIT_FOR_ACTION);
yield put({
type: START_ACTION
});
yield delay(100);
yield take(channel);
yield put({
type: END_ACTION
});
}
<script src="https://cdn.jsdelivr.net/npm/redux-saga@1.1.3/dist/redux-saga.umd.min.js"></script>

关于javascript - 使用带有 take 和 delay 的 runSaga 进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56149372/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com