angular-ngrx一次飞行中有一个请求
上下文:Angular 4.x,RxJs 5.4.x,NgRx 4.1.1.
目标:当多个组件请求相同的数据时,我希望避免重复相同的api调用.我不想取消飞行中的请求,只是在飞行中的请求完成之前不要取得未来的请求. 方法:在商店中有一个名为isFetching的标志.在我的效果中,我检查标志,看看是否已经有飞行中的请求.如果是,那么我不提出请求.触发效果的相同操作会将isFetching标志设置为true. 问题:在运行效果之前更新状态.因此,在发送第一个请求之前,isFetching是真的.所以没有发送任何请求. 示例:以下是问题的简化版本: state.ts export interface State { isFetching: boolean; } reducer.ts export function reducer(state: State,action: Action): State { switch (action.type) { case 'FETCH': return <State>{ isFetching: action.payload }; } return state; } effect.ts @Effect() public fetch: Observable<Action> = this.actions.ofType('FETCH') .withLatestFrom(this.store.select(x => x.isFetching),(_,x) => x) .filter(x => !x) .switchMap(action => this.api.getData() .map(data => new FetchSuccess(data)) .catch(() => Observable.of(new FetchFailure())) ); 想法#1: 我可以通过在包含效果的类中保留变量来复制状态.我会在api请求发出时设置它并使用它来过滤掉将来的请求. effect.ts public isFetching = false; @Effect() public fetch: Observable<Action> = this.actions.ofType('FETCH') .filter(() => !this.isFetching) .switchMap(action => { this.isFetching = true; return this.api.getData() .map(data => new FetchSuccess(data)) .catch(() => Observable.of(new FetchFailure())) .do(() => this.isFetching = false); }); 想法#2: 没有’FETCH’动作集isFetching.让效果发出两个动作.第一个(IsFetching)设置状态,第二个(FetchSuccess | FetchFailure)是结果.我不喜欢我需要两个动作去做我觉得我应该能做的事情.优点是,如果有多个’FETCH’请求,则IsFetching操作只会有一个状态更新. 似乎效果的结果异步应用于状态.因此,顺序同步’FETCH’动作将在标志设置为状态之前触发相同数量的请求.所以不要使用这个解决方案. effect.ts @Effect() public fetch: Observable<Action> = this.actions.ofType('FETCH') .withLatestFrom(this.store.select(x => x.isFetching),x) => x) .filter(x => !x) .switchMap(action => this.api.getData() .map(data => new FetchSuccess(data)) .catch(() => Observable.of(new FetchFailure())) .startWith(new IsFetching(true)) ); 题 解决方法
一种选择是使用维持其自身状态的运算符.
例如,您可以使用distinct,它接受第二个参数,在发出时清除运算符的内部状态: @Effect() public fetch: Observable<Action> = this.actions .ofType('FETCH') .distinct(() => 'FETCH',this.actions.ofType( 'FETCH_SUCCESS','FETCH_FAILURE' )) .switchMap(action => this.api.getData() .map(data => new FetchSuccess(data)) .catch(() => Observable.of(new FetchFailure())); ); 如果键选择器始终返回相同的值,则在处理一个时将收到的任何FETCH操作都将被忽略. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |