【问题标题】:Can an ngrx effect dispatch the same action twicengrx 效果能否分派相同的动作两次
【发布时间】:2021-02-15 03:54:32
【问题描述】:

我有一个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);
    
  }

“EFFECT handleLookupListShouldRefresh has FIRST...”被记录了两次。 “getLookupList has payload...”被记录了两次。 “EFFECT handleLookuplistShouldRefreshEffect has SECOND...”记录一次。

显然我在组织这段代码的方式上做错了。谁能看到我做错了什么?

【问题讨论】:

    标签: angular rxjs ngrx


    【解决方案1】:

    好的,所以我想通了。问题在于我在 handleLookuplistShouldRefreshEffect 中使用 switchMap

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

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

    这解释了为什么我总是收到最后一个请求而不是之前的请求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-11
      • 2019-02-12
      • 2019-03-19
      • 2019-02-25
      • 2018-11-22
      • 1970-01-01
      • 2019-01-31
      • 1970-01-01
      相关资源
      最近更新 更多