我可以在NgRx效果中使用的RxJs switchMap中使用async/await吗



我正在启用Angular NgRx的应用程序中设置新的效果模块。

当我打开一个视图时,我想提出一些请求。由于有许多请求,我想将它们放入自己的方法中,并让它们分派successfailed操作。这些请求的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),
)),
)
);

最新更新