javascript - Angular/TS promise 会导致乱序执行吗?

标签 javascript angular typescript promise routes

我们有一个为我们编写的 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使用 promise 来完成它的工作,因此代码可能会在页面实际更改之前返回以获取下一个消息队列项。我只是想要一个有更多 Angular nous 的人来检查我的推理,或者让我知道我的建议是否是垃圾。至于我的建议:
  • 数字输入关闭,消息 (OFF) 从后端到前端排队。后端也会关闭背光。
  • 数字输入再次快速开启,一条消息 (ON) 从后端到前端排队。后端还会重新激活背光。
  • 前端接收OFF消息并进行处理。因为我们在不在空白页时收到了一条关闭消息,所以我们调用 navigateByUrl('/blank')这启动了一个 promise 。
  • 之前 该 promise 可以实现(并且 routerState.state.url 从非空白变为空白),我们开始处理 ON 消息。在这个阶段,我们有一个带有(陈旧)非空白页面的 ON 消息,所以 forceNavigateIfNeeded()什么也没做。
  • 进行中 navigateByUrl('/blank') promise 完成,将页面设置为空白。

  • 现在我们似乎有了最初描述的情况,背光打开的空白页面。
    这甚至可以用 Angular/Typescript 实现吗?它似乎依赖于这样一个事实,即传入的消息被排队并尽快采取行动(以单线程方式),而前端导航(更重要的是,您当前页面的更新记录)可能需要一段时间。
    有人可以建议这是否可行,如果可行,有什么好的解决方法?
    我认为在 forceNavigateIfNeeded() 等待是个坏主意为了完成 promise ,但我不知道还能怎么做。

    最佳答案

    尽管您的问题非常复杂,但我可以看到一个值得检查的可疑代码。

    ...
    withLatestFrom(this.store.pipe(select(getRouterState))),
    ...
    
    这可能是导致您出现问题的原因,因为它正在获取最新信息。它不会请求更新,也不会等待更新。我们遇到了类似的问题,毫秒也在起作用,我想出了解决方法,我替换了 withLatestFromswitchMap运算符(operator)。我不确定它是否适用于您的情况,但您可以尝试一下。
    map((action: AppActions.ReceiveDigitalInput) => action.payload),
    switchMap(data => //data === action.payload
     this.store.select(getRouterState).pipe(map(routerState => ({ data, routerState }))
    ),
    tap(({data, routerState}) => { ... }
    
    编辑:
    在我们的例子中,我们在 switchMap 中使用了一个自定义选择器。 ,它比较当前和以前的状态并返回比较结果。老实说,我不是 100% 确定这是否也对您有帮助,但在我们的案例中这是一个必要的拼图。
    export const getFeshRouterState= pipe(
      select(getRouterState),
      startWith(null as RouterStateInterface),
      pairwise(),
      map(([prev, curr]) => /* do some magic here and return result */),
    );
    
    抱歉最初的困惑。

    关于javascript - Angular/TS promise 会导致乱序执行吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67412249/

    相关文章:

    json - 使用 Electron 在 Angular 5 中访问文件系统

    angular - 从 window.object 访问 Angular NgZone 实例

    javascript - 如何在javascript中根据日期显示数组

    c# - 如何将自定义 header 添加到 SignalR 的 Typescript 客户端?

    javascript - python 3 : How to extract url image?

    javascript - 使用javascript将彩色图像转换为黑白图像

    Javascript 创建 HTML 对象与创建 HTML 字符串

    angular - Spring云服务- Eureka

    javascript - Angular 5从父组件中的数组中删除对象

    javascript - 如何从由 no-js 类组成的网页中转储表格数据?