angular - RxJS 主题/可观察问题
问题描述
我正在尝试将 Angular 函数转换为可观察模式,因为它的当前实现与它有一些异步性。为了讨论的目的,举这个简单的例子。
aFunction(x: boolean){
if(x){
// ... do something asynchronous based on the value of x
}
}
可以通过以下方式将其转换为使用 Observable:
anObservableFunction(x: boolean): Observable<any> {
const result = new Subject();
if(x){
// ... do something asynchronous based on the value of x
// ... where once the actual value you want to return to
// the subscribing functions, you can pass in the
// result.next(value);
// result.complete();
}
return result.asObservable();
}
我面临的问题(据我的理解)是针对未访问内部选择语句的情况。
anObservableFunction(x: boolean): Observable<any> {
const result = new Subject();
if(x){
// ... do something asynchronous based on the value of x
// ... where once the actual value you want to return to
// the subscribing functions, you can pass in the
// result.next(value);
// result.complete();
} else {
// here
}
return result.asObservable();
}
如果使用常规主题,订阅函数肯定不会获得任何值,因为事件的顺序是:
- 函数被调用
- 主题已创建
- 值已设置
- 调用函数订阅,因此仅在此事件发生后获取值
如果使用 BehaviorSubject 或 ReplaySubject,它们的初始/构造值将被保留,导致订阅事件不必要地触发?
解决方案
如果值是同步发出的,那么使用 Subject 会出现问题是正确的。BehaviorSubject 具有不必要的初始值的缺点,但 ReplaySubject 实际上没有该值并且可以工作,但如果有人稍后订阅您可能不想要的方式,它也会重播此值。
一个简单的技巧是将同步发射延迟一个滴答声:
setTimeout(() => result$.next(42), 0);
但是,您也可以直接返回 observable 并避免使用主题:
foo(x) {
if(x) {
return callRemoteEndpoint();
}
return of(42);
}
推荐阅读
- loops - 为什么我的程序没有输出到 8086 模拟器中给定数组中的最小值?
- python - 将一台设备上的计算时间转换为另一台设备的正确方法是什么?
- python - Sobel过滤错误结果
- java - 字体大小未反映在 IText 中
- java - java.lang.ClassCastException 将类 com.package1.Class1 的对象转换为 com.package2.Class2 的对象
- python - python selenium在移动版网页上找不到可点击的播放按钮
- cuda - 为 GPU 编译 Darknet 时出现分段错误
- swift - 如何使滑块值保留一位小数?
- c# - 当 PInvoke C/C++ DLL 调用退出 (-1) 时 C# 主机应用程序关闭;
- jquery - 检查是否选择了选项