我有一个关于redux传奇的问题,有没有任何方法可以实现takeLatest,但有条件。
例如,我有一个歌曲类型的动态列表(说唱、流行、嘻哈…(,我想按歌曲类型获取歌曲。我定义了一个类型为";"FETCH_SONGS_BY_TYPE";然后将songType传递给它。操作将看起来像
// actions
const fetchSongsByType = songType => ({
type: FETCH_SONGS_BY_TYPE,
songType
});
--------------------------------------------------
//saga
function* fetchSongsByTypeSaga(action) {
// request songs list by action.songType
}
function* Saga() {
yield takeLatest(FETCH_SONGS_BY_TYPE, fetchSongsByTypeSaga);
}
因此,我希望只有在下一次传奇运行具有相同的歌曲类型时,才能取消上一次传奇任务。
在上面的代码中,我得到了这个:
- fetchSongs-歌曲类型:Hip_hop(由于[2]而取消(
- fetchSongs-歌曲类型:说唱(由于[3]而取消(
- fetchSongs-歌曲类型:流行音乐(由于[4]而取消(
- fetchSongs-歌曲类型:说唱(由于[5]而取消(
- fetchSongs-歌曲类型:流行
但我原以为会是这样的:
- fetchSongs-歌曲类型:Hip_hop
- fetchSongs-歌曲类型:说唱(由于[4]而取消(
- fetchSongs-歌曲类型:流行音乐(由于[5]而取消(
- fetchSongs-歌曲类型:说唱
- fetchSongs-歌曲类型:流行歌曲
我感谢您的帮助,提前谢谢。
如果你看一下takeLatest的文档,你会发现这种效果是如何使用低级效果构建的。有了这个例子,你可以很容易地创建你的自定义效果,只会取消同一音乐流派的动作。
takeTlatestByType:
const takeLatestByType = (patternOrChannel, saga, ...args) => fork(function*() {
// hold a reference to each forked saga identified by the type property
let lastTasks = {};
while (true) {
const action = yield take(patternOrChannel);
// if there is a forked saga running with the same type, cancel it.
if (lastTasks[action.type]) {
yield cancel(lastTasks[action.type]);
}
lastTasks[action.type] = yield fork(saga, ...args.concat(action));
}
});
用法:
function* Saga() {
yield takeLatestByType(FETCH_SONGS_BY_TYPE, fetchSongsByTypeSaga);
}