反弹和取消可重复观察
我正在尝试创建一个简单的可重构可观察史诗,它可以反弹并且可以取消。我的代码:反弹和取消可重复观察
export const apiValidate = action$ => {
return action$.ofType(validateRequestAction)
.debounceTime(250)
.switchMap((action) => (
Observable.ajax({
url: url,
method: 'GET',
crossDomain: true,
headers: {
"Content-Type": 'application/json'
},
responseType: 'json'
})
.map(payload => (new APISuccessValidate()))
.takeUntil(action$.ofType(validateCancelAction))
.catch(payload => ([new APIFailureValidate()]))
));
};
代码只有时才有效。根据服务器的响应速度,我认为可能会出现两种情况之一。
情景1(作品):
Time 0ms - Fire validateRequestAction
Time 250ms - Ajax request occurs
Time 251ms - Fire validateCancelAction
Time 501ms - validateCancelAction passes debounce and cancels properly
Nothing else occurs
方案2(断)
Time 0ms - Fire validateRequestAction
Time 250ms - Ajax request occurs
Time 251ms - Fire validateCancelAction
Time 400ms - Ajax returns, APISuccessValidate action fired
Time 501ms - validateCancelAction passes debounce and there is nothing to cancel
有没有一种方法,我可以写我的史诗,使得只有validateCancelAction可以绕过debounceTime并取消阿贾克斯呼吁没有等待?
谢谢!
你实际上只是在清除你的匹配validateRequestAction
,但你的.takeUntil(action$.ofType(validateCancelAction))
没有任何反弹。我可能是错的,但是如果可以在之前发送取消动作该动作已经超过了去抖动,那么取消该动作将会取消而不是,因为ajax请求没有取消开始了,也没有takeUntil
。通过不允许取消直到你的副作用(本例中的ajax)已经开始并且takeUntil
正在倾听可能的取消。
在您的用户界面中,您不会让用户能够取消,直到设置了某种状态为止。由于我们的史诗需要告诉redux何时翻转,我们需要发出一个动作,我们将在减速器中侦听。
最简单的方法是使用startWith
操作:
export const apiValidate = action$ => {
return action$.ofType(validateRequestAction)
.debounceTime(250)
.switchMap((action) => (
Observable.ajax({
url: url,
method: 'GET',
crossDomain: true,
headers: {
"Content-Type": 'application/json'
},
responseType: 'json'
})
.map(payload => (new APISuccessValidate()))
.takeUntil(action$.ofType(validateCancelAction))
.catch(payload => ([new APIFailureValidate()]))
.startWith({ type: 'validateRequestActionStarted' }) // <-- here
));
};
因此,在这个例子中,一些减速会听validateRequestActionStarted
,并改变一些国家的UI便会知道,我们应该给他们取消的能力。
阻止那场比赛将是takeUntil
的顶级流完全和一个完全不同的方式则刚刚“重启”使用repeat
,如果它被取消的史诗。所以这会在我们取消时关闭所有的东西。任何悬而未决的ajaxs和任何未决的debounces。
export const apiValidate = action$ => {
return action$.ofType(validateRequestAction)
.debounceTime(250)
.switchMap((action) => (
Observable.ajax({
url: url,
method: 'GET',
crossDomain: true,
headers: {
"Content-Type": 'application/json'
},
responseType: 'json'
})
.map(payload => (new APISuccessValidate()))
.catch(payload => ([new APIFailureValidate()]))
))
.takeUntil(action$.ofType(validateCancelAction))
.repeat();
};
值得一提的是,我使用的术语史诗,并重新启动,以帮助我们的概念化特定领域,但这大多只是正常RxJS所以它的终极版,可观察到的普遍适用的外面。一个“史诗”只是我们的一个函数模式的一个词,它接受一系列操作(输入)并返回一系列操作(输出)。
感谢您花时间解释我对抖动动作的误解,这对我帮助了很多,正确理解了这个问题。我尝试了你提供的第二个解决方案,它完美的工作!我也不知道startWith,我相信这将在未来派上用场。 非常感谢! –
不客气!我强烈建议花一些时间真正理解_why_它的作品:)祝你好运! – jayphelps
是的,我现在正在通过所有文档工作=) –