Ale*_*sky 1 reactjs redux redux-saga
是否有可能通过Redux Saga中的副作用之类的方法来取消eventChannel?
给定eventChannel与外部事件/数据流的连接,在这种情况下为Firebase实时数据库"child_added"事件:
// action
const types = { SYNC: 'SYNC_TODOS' };
function syncTodos(todos) {
return { types: types.SYNC, todos }
}
// saga
function todosChannel() {
// firebase database ref
const ref = firebase.database().ref('todos/');
const channel = eventChannel(emit => {
const callback = ref.on('child_added', (data) => {
emit({ snapshot: data, value: data.val() })
});
// unsubscribe function
return () => ref.off('child_added', callback);
});
return channel;
}
function* sync() {
const channel = yield call(todosChannel);
try {
while (true) {
const { value } = yield take(todosChannel);
yield put(actions.syncTodos(value));
}
}
finally {
if(yield cancelled()) {
channel.close();
}
}
}
export default function* rootSaga() {
yield fork(sync);
}
Run Code Online (Sandbox Code Playgroud)
有什么方法可以将诸如fork()之类的有效端与takeEvery()之类的内容一起使用,以监听取消事件通道并停止监听Firebase "child_added"事件/数据流的操作?还是这需要以某种方式保存对通道的引用并在通道引用本身上执行cancel()?
感谢您提供任何帮助。
我不得不稍微修改接受的答案方法以捕获我的频道中发出的错误。我也更喜欢在分叉中处理取消,而不是像接受的答案那样分叉处理值。
function* sync() {
const channel = yield call(todosChannel);
yield fork(function* () {
yield take('CANCEL_WATCH')
channel.close();
})
try {
while (true) {
const { value } = yield take(channel)
yield put(actions.syncTodos(value))
}
}
catch (error) {
yield put(actions.cancelWatch()) // to emit 'CANCEL_WATCH'
yield put(actions.errorTodos(error))
}
}
Run Code Online (Sandbox Code Playgroud)
你是这个意思?
function* sync() {
const channel = yield call(todosChannel);
yield takeEvery(channel, function*({value}){
yield put(actions.syncTodos(value))
}
yield take('CANCEL_WATCH')
channel.close();
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,takeEvery是帮助者,不是效果。
| 归档时间: |
|
| 查看次数: |
2218 次 |
| 最近记录: |