我正在启用Angular NgRx的应用程序中设置新的效果模块。
当我打开一个视图时,我想提出一些请求。由于有许多请求,我想将它们放入自己的方法中,并让它们分派success
或failed
操作。这些请求的API都是async
方法(它们返回一个承诺(
我有以下
public viewOpened$ = createEffect(() => this.actions$.pipe(
ofType(myActions.viewOpened),
// Use a switchMap to cancel any ongoing subscriptions if request new comes in
switchMap(_ => {
(async () => {
this.logger.info('view Opened');
const p1 = this.request1();
const p2 = this.request2();
// await so switchMap can handle any race conditions
await Promise.all([p1, p2]);
});
// Need to return an observable (but this is not used)
return of({})
})
), { dispatch: false });
我正在使用CCD_ 4,希望它能照顾任何";比赛条件";对我来说,也就是说,如果视图快速打开、关闭,然后再次打开,switchMap将取消任何以前未完成的请求。
但我在上面发现,async
内部的代码从未被调用。
我的async
代码没有被调用是有原因的吗?我上面试图做的事情可能吗?
您正在用括号包装异步调用,此时您必须使其成为立即调用的异步函数表达式。基本上,在将异步函数表达式封装在圆括号中之后,您会缺少一些执行异步函数的圆括号。我认为它应该类似于:(async () => {...})()
与其使用promise,为什么不让您的请求变得可观测?您可以从switchMap
返回forkJoin
,如下所示:
switchMap(_ => {
// p1 and p2 are Observables
const p1 = …;
const p2 = …;
return forkJoin([p1, p2]);
})
我在效果的switchMap中使用异步等待也有类似的问题。原始代码
someEffect$ = createEffect(() => this.actions$
.pipe(
ofType(actionRelatedToEffect),
withLatestFrom(this.store$.select(e => e.portfolioDocumentDistribution)),
switchMap(([actionProp, state]) =>
this.httpService.internalApiPost(
'web api endPoint Path',
createRequestPayload(param),
() => call Action-1,
undefined,
() => call Action-2,
)),
)
);
现在createRequestPayload已转换为异步等待函数因此,要在上面的switchMap中使用该方法,需要使用await关键字进行调用然后ide强制将整个块转换为异步,如下所示
someEffect$ = createEffect(() => this.actions$
.pipe(
ofType(actionRelatedToEffect),
withLatestFrom(this.store$.select(e => e.portfolioDocumentDistribution)),
switchMap(async ([actionProp, state]) =>
this.httpService.internalApiPost(
'web api endPoint Path',
await createRequestPayload(actionProp, state),
() => call Action-1(actionProp, state),
undefined,
() => call Action-2(actionProp, state),
)),
)
);
但不知怎么的,IDE再次抱怨出现了一些神秘的复杂错误因此,我通过引入另一个switchMap来解决这个问题,并将请求有效载荷传递给下面的switchMap,如下所示
someEffect$ = createEffect(() => this.actions$
.pipe(
ofType(actionRelatedToEffect),
withLatestFrom(this.store$.select(e => e.portfolioDocumentDistribution)),
switchMap(async ([actionProp, state]) => {
const payload = await createRequestPayload(actionProp, state);
return {
actionProp,
state,
payload
};
}),
switchMap(param =>
this.httpService.internalApiPost(
'web api endPoint Path',
param.payload,
() => call Action-1(param.actionProp, param.state),
undefined,
() => call Action-2(param.actionProp, param.state),
)),
)
);