我实现了一个redux效果takeLeading
,如果saga当前正在运行,它将忽略后续操作:
export const takeLeading = (patternOrChannel, saga, ...args) => fork(function*() {
while (true) {
const action = yield take(patternOrChannel);
yield call(saga, ...args.concat(action));
}
});
我在我的应用程序中使用它来进行API提取,其中我的API中的每个端点都有自己的操作类型。因此,对于GET
方法,如果请求已经在应用程序中的其他位置分派,则阻止它是有用的。传奇看起来像:
return function* () {
yield all([takeLeading(GET_USER_ID, callApiGen), takeLeading(GET_WIDGET_ID, callApiGen)]);
}
显而易见的问题是,如果我想获得两个不同的用户ID,则第二个将阻止,因为它也具有操作类型GET_USER_ID。如果没有为每个可能的参数做出不同的操作,有没有办法实现一些takeLeadingForFunc(<action>, (action) => <id>, saga)
,这允许我保持每个请求类型指定一个效果的简明格式,但允许我不阻止{{1} } 是不同的?我试图用<id>
包裹takeLeading
来实现某些东西但却无法完成它。
编辑:
我有这样的工作:
takeEvery
它需要一个应该返回原语的提取器函数export const takeLeadingForFunc = (f) => (patternOrChannel, saga, ...args) => fork(function*() {
let takeLeadings = {};
while (true) {
const action = yield take(patternOrChannel);
if (!(f(action) in takeLeadings)) {
yield call(saga, ...args.concat(action))
takeLeadings[f(action)] = yield takeLeading((ac) => f(ac) === f(action) && ac.type === action.type, saga, ...args)
}
}
});
。这有点像hacky,所以想知道是否有更惯用的方法来做到这一点。