BehaviorSubject .next() 未发出更新值

如何解决BehaviorSubject .next() 未发出更新值

我只是想为我对 RxJS 和 Observables 缺乏了解而道歉。我之前发布了一个问题,但措辞很差,我知道这是无法理解的,所以一天后我想我可以更好地解释我的问题。

  1. 我的代码的目标是获取用户输入,将其作为动作流传递给我的数据流,将输入与我的托架数组进行比较,如果存在,则返回该单个托架。如果它不存在(这是我苦苦挣扎的地方)返回一个可观察的对象,我可以在我的 bay.page.ts 中调用它并检查它的 true 或 { {1}}。如果是 false [显示客户端错误]。 如果是 false,请向前导航到结果页面。
  2. 我的 true 类包含我的数据和操作流:
bay-service.ts

^ 在上面的代码中,我使用了声明式 RxJS 方法 export class BayServiceService { private baysUrl = 'api/bays'; bays$ = this.http.get<Bay[]>(this.baysUrl) .pipe( tap(data => console.log('Bays: ',JSON.stringify(data))),catchError(this.handleError) ); /*--------------------------------------------------------------*/ // Grab A Single Bay private baySelectedSubject = new BehaviorSubject<number>(0); baySelectedAction$ = this.baySelectedSubject.asObservable(); invalidBay = new BehaviorSubject<boolean>(false); selectedBay$ = combineLatest([ this.bays$,this.baySelectedAction$ ]) .pipe( map(([bays,selectedBayNumber]) => { if (!bays.find(bay => bay.bayCode === selectedBayNumber)){ this.invalidBay.next(false); } else { this.invalidBay.next(true); return bays.find(bay => bay.bayCode === selectedBayNumber); } }),); selectedBayChanged(selectedBayNumber: number): void { this.baySelectedSubject.next(selectedBayNumber); } ,其中我将 selectedBay$ 数据流和 bay$ 操作流(其中包含用户输入)组合在一起。然后我将它们映射,然后将用户输入 baySelectedAction$ 与单个托架编号进行比较。

问题:我正在尝试使用我在 selectedBayNumber 中创建的 Observable -> invalidBay = new BehaviorSubject<boolean>(false); 并检查它的结果:如果为真,则向前导航。如果它是假的,则显示它不存在的客户端错误。 但是,如果用户输入有效的托架编号,我会尝试通过执行 bay-service.ts 将该 Observable 更改为 true 但是,Observable 不会更新它的值? BehaviorObservable 保持其默认值“false”。所以代码部分工作,但不完全。

  1. 这是我的 this.invalidBay.next(true); 中的 onSubmit 方法,我在其中处理操作流的用户输入。我将用户输入传递给一个方法(在我的 bay-page.ts 类中)。根据他们的输入,我尝试订阅“应该更新”的 Observable 并从那里开始。但是 Observable 没有被更新。请帮忙。
bay-service.ts

为什么 Observable 的值没有更新?拜托,我的心很痛,我不知道还能做什么。

解决方法

如果没有观察者订阅一个可观察对象,则它什么也不做。您没有订阅 selectedBay$ 可观察对象。因此,来自 combineLatest 的管道中的代码根本没有执行,无论新值向您的操作流发出多少次,并且您始终从 {{1} 接收初始 false 值}.

一些建议:

  1. invalidBay 是一个多播的 observable,你应该始终保持它的私密性,以尽量减少在它上面调用 BehaviorSubject 的范围。使用 next() 方法将其公开为 observable,如果任何外部代码需要发出新值的能力,请提供一个公共方法来执行此操作。您已经在以这种方式处理 .asObservable()。考虑对 baySelectedSubject 做同样的事情。

  2. 切勿将您的订阅代码放在将执行多次的方法中。每次执行该方法时,您最终都会创建一个新订阅。 observable 将向每个订阅发出值。因此,请从 invalidBay 中删除您的订阅并将其放入 onSubmit()

  3. 如果您没有使用它,请避免存储 ngOnInit() 引用。您可以简单地订阅为 -

Subscription

代替 -

this.bayService.invalidBay$.subscribe(value => ...

如果你确实需要一个 this.subscription = this.bayService.invalidBay.subscribe(value => ... 引用,那么记得在 Subscription 方法中进行清理 -

ngOnDestroy

一旦您的组件被销毁,这将取消订阅 observable。否则,即使您的组件被销毁,ngOnDestroy(): void { this.subscription.unsubscribe(); } 引用仍会保留可观察对象,这最终会导致内存泄漏。

基于建议的(相对)更好的实施:

服务-

Subscription

在您的组件中 -

export class BayServiceService {
    private baysUrl = 'api/bays';

    bays$ = this.http.get<Bay[]>(this.baysUrl)
        .pipe(
            tap(data => console.log('Bays: ',JSON.stringify(data))),catchError(this.handleError)
        );

    private baySelectedSubject = new BehaviorSubject<number>(0);
    baySelectedAction$ = this.baySelectedSubject.asObservable();

    private invalidBay = new BehaviorSubject<boolean>(false);
    invalidBay$ = this.invalidBay.asObservable();

    selectedBay$ = combineLatest([this.bays$,this.baySelectedAction$])
        .pipe(
            map(([bays,selectedBayNumber]) => {
                let bay = bays.find(p => p.bayCode === selectedBayNumber);
                if (!bay) {
                    this.invalidBay.next(false);
                } else {
                    this.invalidBay.next(true);
                    return bay;
                }
            }));

    selectedBayChanged(selectedBayNumber: number): void {
        this.baySelectedSubject.next(selectedBayNumber);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res