ngrx效果可以两次分发相同的动作吗?

时间:2020-11-02 13:24:41

标签: angular rxjs ngrx

我有ngrx效果。从这个效果来看,我想触发对同一ngrx动作但具有不同参数的多个调用。这是我目前正在做的事情:

@Effect({dispatch: true}) 
    public handleNodeWillReceiveFocus$ = this.actions$
    .pipe(
      ofType(nodeWillReceiveFocus),
      concatMap( payload => [
      
        lookuplistShouldRefresh({listname:"billboards"}),
        lookuplistShouldRefresh({listname:"microforms"}),
        
        nodeDidReceiveFocus(payload),
        
      ]),
      
      ); 

动作如下:

import { createAction, props } from '@ngrx/store';
export const lookuplistShouldRefresh = createAction(
  '[lookuplists] lookuplistShouldRefresh',
  props<{ listname:string }>()
);

我正在观察的行为是似乎只调度了一个lookuplistShouldRefresh动作(最后一个)。如果我调换了两个电话,那么我会收到“广告牌”电话。

这两种动作都会导致商店突变。

是否可以从具有不同参数的效果中多次分派相同的动作?我以为concatMap可以连续运行所有内容...?

更新:我添加了一些日志记录,并且正确分配了这两个操作,但是其他地方不正确。

这是第二个效果处理程序:

export class handleLookuplistShouldRefreshEffect {

    constructor(
        private actions$: Actions,
        private lookuplistAPI: LookuplistAPIService,
      ) {}

      
    @Effect({dispatch: true}) 
    public handleLookupListShouldRefresh$ = this.actions$
    .pipe(
      ofType(lookuplistShouldRefresh),
      tap((payload) => {
        console.log(`EFFECT handleLookupListShouldRefresh has FIRST ${JSON.stringify(payload)}`);
      }),
      switchMap((payload) => this.lookuplistAPI.getLookupList(payload)),
      tap((payload) => {
        console.log(`EFFECT handleLookuplistShouldRefreshEffect has SECOND ${JSON.stringify(payload)}`);
      }),
      concatMap( payload => [
        lookuplistDidRefresh({listname:payload["listname"],items:payload["items"]}),
        
      ]),
      
      );

}

API如下所示:

export class LookuplistAPIService {

  constructor(private store: Store, private zhttpSvc: ZhttpService) { }

  getLookupList(payload){
    try{
      
      console.log(`getLookupList has payload: ${JSON.stringify(payload)}`);
      const path = this.getPathFromListname(payload.listname);
      
      return this.zhttpSvc.httpGet(path);
       
    }catch(exc){
      console.log(`BANG in getLookupList`);
      return of({});
    }
  }

  getPathFromListname(listname){
    switch(listname){
      case "microforms":
        return "/microform/lookuplist";
        break;
      case "billboards":
        return "/billboard/lookuplist";
        break;
    }
    
  }
}

httpGet看起来像这样:

public httpGet(path){
    
    
    const options = {
      withCredentials: true // Allows cookies to be read/set
    };

    
    return this.http.get(`${environment.apiUrl}${path}`,options);
    
  }

“有效的handleLookupListShouldRefresh具有FIRST ...”被记录两次。 两次记录“ getLookupList具有有效负载...”。 记录一次“ EFFECT handleLookuplistShouldRefreshEffect具有SECOND ...”。

显然,我在组织这段代码的方式上做错了。有人可以看到我在做什么错吗?

1 个答案:

答案 0 :(得分:1)

好的,所以我知道了。问题是我在handleLookuplistShouldRefreshEffect中使用switchMap

switchMap将开始处理第一个请求,但是将在第二个请求到达时立即取消第一个请求。它“切换”到第二个发射。

我将switchMap更改为flatMap-flatMap会将所有排放扁平化为流,而不会取消任何当前正在运行的进程。

这解释了为什么我总是收到LAST请求而不是以前的请求。