angular - 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);
}
“EFFECT handleLookupListShouldRefresh has FIRST ...”被记录两次。“getLookupList has payload...”被记录了两次。“EFFECT handleLookuplistShouldRefreshEffect has SECOND ...”记录一次。
显然,我在组织这段代码的方式上做错了。谁能看到我做错了什么?
解决方案
好的,所以我想通了。问题在于我在 handleLookuplistShouldRefreshEffect 中使用 switchMap
switchMap 将开始处理第一个请求,但会在第二个请求到达后立即取消第一个请求。它“切换”到第二次发射。
我将 switchMap 更改为 flatMap - flatMap 会将所有排放压平到流中,而不会取消任何当前正在运行的进程。
这解释了为什么我总是收到最后一个请求,而不是之前的请求。
推荐阅读
- azure-devops - 跨项目克隆 Azure DevOps 工作项
- java - Domino 服务器:仅将 JVM 选项传递给 http 任务
- python - 如何在数据框中展开列,其中包含需要在熊猫中展开的每一行的完整列表?
- laravel - 使用 Laravel 启动 Docker 容器时,*有时*会触发导致 HTTP 500 的“类视图不存在”
- google-sheets - 阻止其他用户使用 Google 脚本
- oracle - 重命名查询中使用的表时,物化视图无效。ORA-00942 和 ORA-06512,oracle 19c
- cypress - 缺少 APPLITOOLS_API_KEY 环境变量
- android - Glide 可以在 Android TextView 中渲染 ImageSpan 吗?
- python - 如何在 embed mod 中更改 Ipython 输入/输出提示
- python - 根据标题python的名称和数量订购原始数据