服务器上取消了多个 API 调用
Posted
技术标签:
【中文标题】服务器上取消了多个 API 调用【英文标题】:multiple API calls canceled on server 【发布时间】:2019-12-15 18:49:33 【问题描述】:我正在使用 Angular7 和 NGRX,以及 GO 中的服务器。
我的ngrx效果中有以下代码=>
//#region OPEN CHANNELS
@Effect()
getUAVsSuccess$ = this.actions$.pipe(
ofType<featureActions.GetUAVsSuccess>(featureActions.ActionTypes.GetUAVsSuccess),
concatMap(action =>
of(action).pipe(
withLatestFrom(this.store$.pipe(select(featureSelectors.selectAll))),
withLatestFrom(this.store$.pipe(select(OrganizationStoreSelectors.selectedOrganizationId))),
withLatestFrom(this.store$.pipe(select(ProjectsStoreSelectors.selectedProjectId)))
)
),
switchMap(([[[action, drones], organizationId], projectId]) =>
const actions = [];
drones.forEach((drone) =>
actions.push(
new featureActions.OpenUAVUpdatePositionChannelRequest( uavId: drone.uavId, projectId, organizationId ),
new featureActions.OpenUAVUpdateStatusChannelRequest( uavId: drone.uavId, projectId, organizationId ),
new featureActions.GetUAVCurrentMissionRequest(uavId: drone.uavId)
);
);
return actions;
),
);
基本上这样会打开2个频道,然后得到一个任务。
最后一个动作,将派发另一个效果
@Effect()
getCurrentMission$ = this.actions$.pipe(
ofType<featureActions.GetUAVCurrentMissionRequest>(featureActions.ActionTypes.GetUAVCurrentMissionRequest),
switchMap((action) =>
this.dataService.getCurrentMission(action.payload).pipe(
switchMap(response => [
new featureActions.GetUAVCurrentMissionSuccess(uavId : action.payload.uavId, missionHandler : response.identifier),
new MissionsStoreActions.GetMissionUAVRequest(uavId : action.payload.uavId, missionHandler : response.identifier)
]),
catchError((error: HttpErrorResponse) =>
this.snackBar.open(this.translate.instant('ERROR.HTTP.DRONE.NOT_UPDATABLE', message: error.message), this.translate.instant('BUTTON.OK'), duration: 2500);
return of(new featureActions.GetUAVCurrentMissionFailed(error));
),
)
)
);
那个,使用 api 调用 getCurrentMission
会向服务器询问任务
getCurrentMission(params: uavId: number): Observable<apiModels.GetMissionHandleResponse>
return this.httpClient.get<any>(`$environment.API_URL/mission/get_mission_handle_uav?uavID=$params.uavId`);
现在,我面临的问题是。如果我装载 4 架无人机,我总共将有 12 个呼叫。最后一次接听电话被取消了,因为它就像在短时间内被问了 3 次一样。
我不明白究竟是什么原因造成的。服务器确实得到调用检索数据(我在发送响应之前添加了日志),并发送响应,但是在浏览器上取消了调用,所以我的 ngrx init 调用流程中断了。当时只接听一个电话
可能是什么问题?
编辑:我还尝试在邮递员上运行一系列测试,无延迟地调用 5 次相同的端点,并且它有效。所以我猜ngrx或chrome中的某些东西正在取消我的电话?
【问题讨论】:
【参考方案1】:你正在使用 switchMap 所以
switchMap 与其他扁平化操作符的主要区别 是消音效果。在每次发射上,前一个内部 observable(您提供的函数的结果)被取消并且 订阅了新的 observable(如果新的发射值快速发射 足够的)。
您可以通过短语 switch to a new 来记住这一点 可观察的
所以我建议你像这样更改代码
@Effect()
getCurrentMission$ = this.actions$.pipe(
ofType<featureActions.GetUAVCurrentMissionRequest>(featureActions.ActionTypes.GetUAVCurrentMissionRequest),
mergeMap((action) => // here
this.dataService.getCurrentMission(action.payload).pipe(
mergeMap(response => [ // here
new featureActions.GetUAVCurrentMissionSuccess(uavId : action.payload.uavId, missionHandler : response.identifier),
new MissionsStoreActions.GetMissionUAVRequest(uavId : action.payload.uavId, missionHandler : response.identifier)
]),
catchError((error: HttpErrorResponse) =>
this.snackBar.open(this.translate.instant('ERROR.HTTP.DRONE.NOT_UPDATABLE', message: error.message), this.translate.instant('BUTTON.OK'), duration: 2500);
return of(new featureActions.GetUAVCurrentMissionFailed(error));
),
)
)
);
或者使用exhaustMap
@Effect()
getCurrentMission$ = this.actions$.pipe(
ofType<featureActions.GetUAVCurrentMissionRequest>(featureActions.ActionTypes.GetUAVCurrentMissionRequest),
exhaustMap((action) =>
this.dataService.getCurrentMission(action.payload).pipe(
tap(response => //change to map here
new featureActions.GetUAVCurrentMissionSuccess(uavId : action.payload.uavId, missionHandler : response.identifier),
),
tap(response =>
new MissionsStoreActions.GetMissionUAVRequest(uavId : action.payload.uavId, missionHandler : response.identifier)
),
catchError((error: HttpErrorResponse) =>
this.snackBar.open(this.translate.instant('ERROR.HTTP.DRONE.NOT_UPDATABLE', message: error.message), this.translate.instant('BUTTON.OK'), duration: 2500);
return of(new featureActions.GetUAVCurrentMissionFailed(error));
),
)
)
);
【讨论】:
我已经尝试过 map,但问题是我得到了ERROR Error: Effect "UAVsEffects.getCurrentMission$" dispatched an invalid action: ["payload":"uavId":3,"missionHandler":"2d","type":"[UAV] Get UAV Current Mission Success","payload":"uavId":3,"missionHandler":"2d","type":"[MISSION] Get Mission UAV Request"]
因为我无法使用简单的 map 调度一系列动作
我也试过mergeMap,但同样的结果有switchMap
或者你在水龙头里面使用this.store.dispatch。它也可以工作
我试过点击,它也取消了请求,但你给了我一个方向,谢谢你会继续调查
您可以在stackblitz.com 或github 上为我分享您的源代码吗?我很想看看以上是关于服务器上取消了多个 API 调用的主要内容,如果未能解决你的问题,请参考以下文章