dou*_*ald 8 generator redux-saga
刚刚从thunk转移到sagas我正试图找到最好的方法来调用setTimeout,然后从该函数内调用另一个函数(在这种情况下corewar.step()).这是我原来的代码,正如我所料.
runner = window.setInterval(() => {
for(let i = 0; i < processRate; i++) {
corewar.step()
}
operations += processRate;
}, 1000/60)
Run Code Online (Sandbox Code Playgroud)
这段代码在a里面saga,我相信我应该可以call像在应用程序的其他区域中那样包装函数调用.
我已经尝试将setInterval调用包装在一个call并保留其他所有内容,这导致step()永远不会被调用.
runner = yield call(window.setInterval, () => {
for(let i = 0; i < processRate; i++) {
corewar.step()
}
operations += processRate;
}, 1000/60)
Run Code Online (Sandbox Code Playgroud)
我已经尝试过,保持setInterval原样并将step()函数包装在一个调用中并更改匿名函数签名,function*这也导致step()永远不会被调用.
runner = window.setInterval(function*() {
for(let i = 0; i < processRate; i++) {
yield call([corewar, corewar.step])
}
operations += processRate;
}, 1000/60)
Run Code Online (Sandbox Code Playgroud)
最后,我尝试包装两者,这再次导致step()永远不会被调用.
runner = yield call(window.setInterval, function*() {
for(let i = 0; i < processRate; i++) {
yield call([corewar, corewar.step])
}
operations += processRate;
}, 1000/60)
Run Code Online (Sandbox Code Playgroud)
感觉就像我在这里遗漏了一些东西所以我的问题是,我是否应该完全包装这些功能call或者这是错的?
接下来的问题是,我是否应该将外部包装setInterval在一个call将是我应该如何定义一个函数作为一个参数call,也想要产生一个put或call自己?
mad*_*adc 11
saga-redux文档中有一节名为" 使用eventChannel工厂连接外部事件 ",建议使用channels.
本节还提供了一个setInterval实现示例:
import { eventChannel, END } from 'redux-saga'
function countdown(secs) {
return eventChannel(emitter => {
const iv = setInterval(() => {
secs -= 1
if (secs > 0) {
emitter(secs)
} else {
// this causes the channel to close
emitter(END)
}
}, 1000);
// The subscriber must return an unsubscribe function
return () => {
clearInterval(iv)
}
}
)
}
Run Code Online (Sandbox Code Playgroud)
然后yield call,您将使用和yield takeEvery设置它:
const channel = yield call(countdown, 10);
yield takeEvery(channel, function* (secs) {
// Do your magic..
});
Run Code Online (Sandbox Code Playgroud)
const anotherSaga = function * () {
const runner = yield call(setInterval, () => {
console.log('yes');
}, 1000);
console.log(runner);
}
Run Code Online (Sandbox Code Playgroud)
这对我来说很好。在第二个片段)的末尾有一个双精度字,应该只有一个。
虽然有点晚了,但这是在传奇中设置计时器问题的最佳搜索结果。由于传奇的性质,有一个替代解决方案。从这里。
我这样调整:
function* callSelfOnTimer({ value }) {
// Do your work here
...
// If still true call yourself in 2 seconds
if (value) {
yield delay(2000);
yield call(callSelfOnTimer, { value });
}
}
Run Code Online (Sandbox Code Playgroud)