【发布时间】:2021-07-28 10:07:58
【问题描述】:
我们有一个为我们编写的 Angular 应用程序,我们正试图找出一个特定的问题(请参阅下面的我的大量文章)。基本上,这是一个系统,其中一些数字输入应该控制背光和显示的页面。如果数字输入打开,背光也应该打开,应用程序应该正常工作,允许用户交互。
但是,如果没有该数字输入信号,应用程序应该给出一个空白页面并关闭背光,这样用户就什么都看不到并且无法以某种盲目的方式与真实页面进行交互。
背光由后端进程控制,该进程还使用 Angular 路由将信息传递到前端(两者都在同一设备上运行)。但是网页上显示的内容完全在前端的控制之下。
我们看到这样一种情况,如果数字输入被快速关闭和打开,我们有时会打开背光但页面是空白的,我想知道在传递事件时是否存在某种竞争条件通过路由器。
在代码方面,我们有一个效果,它监控来自后端(不是直接)的数字输入信号,看起来像:
@Effect({ dispatch: false })
receiveDigitalInputEvent$ = this.actions.pipe(
ofType(AppActionTypes.RECEIVE_DIGITAL_INPUT),
map((action: AppActions.ReceiveDigitalInput) => action.payload),
withLatestFrom(this.store.pipe(select(getRouterState))),
tap(([data, routerState]) => {
const currUrl = routerState ? routerState.state.url : '';
const { isDigitalInputSet, someOtherStuff } = data;
this.forceNavigateIfNeeded(isDigitalInputSet, currUrl);
})
);
forceNavigateIfNeeded(isDigitalInputSet: boolean, currUrl) {
if (isDigitalInputSet && currUrl.endsWith('/blank')) {
this.router.navigateByUrl('/welcome');
else if (! isDigitalInputSet && ! currUrl.endsWith('/blank')) {
this.router.navigateByUrl('/blank');
}
}
这基本上是在数字输入事件到达时:
- 如果输入已打开且屏幕当前为空白,则转到欢迎屏幕;或
- 如果输入关闭并且您当前不在空白屏幕上,请转到空白屏幕。
现在,这可以正常工作,只是快速转换似乎导致了问题。
我对 Angular 内部结构了解不多,但我认为传入的事件正在以某种方式排队等待通过路由机制进行传递(我相信后端通过 Web 套接字将东西推送到前端)。
我查看了 Angular 源代码并注意到 navigateByUrl 使用承诺来完成其工作,因此代码可能会返回以获取下一个消息队列项在页面实际更改之前。我只是希望有更多 Angular nous 的人来检查我的推理,或者让我知道我的建议是否是垃圾。至于什么,我的建议是:
- 数字输入关闭,消息 (OFF) 从后端排队到前端。后端也会关闭背光。
- 数字输入再次快速打开,一条消息 (ON) 从后端排队到前端。后端还会重新激活背光。
- 前端收到 OFF 消息并进行处理。因为我们在不在空白页时收到了 OFF 消息,所以我们调用
navigateByUrl('/blank')来启动一个 promise。 -
在可以实现承诺之前(并且
routerState.state.url从非空白变为空白),我们开始处理 ON 消息。在这个阶段,我们有一个(过时的)非空白页面的 ON 消息,所以forceNavigateIfNeeded()什么都不做。 - 进行中的
navigateByUrl('/blank')承诺完成,将页面设置为空白。
现在我们似乎遇到了最初描述的情况,一个背光打开的空白页面。
Angular/Typescript 甚至可以实现这一点吗?它似乎依赖于这样一个事实,即进入队列并尽快(以单线程方式)对其采取行动,而前端导航(更重要的是,您当前页面的更新记录)可能需要一段时间。
有人可以建议这是否是可能的,如果是,有什么好的方法来解决它?
我认为在forceNavigateIfNeeded() 等待承诺完成是个坏主意,但我不知道该怎么做。
【问题讨论】:
标签: javascript angular typescript promise routes