我需要创建一个可观察对象的订阅,当它第一次被调用时立即被处理。
比如:
observable.subscribeOnce(func);
在我的用例中,我在一个快速路由处理程序中创建了一个订阅,并且每个请求都被多次调用订阅。
我需要创建一个可观察对象的订阅,当它第一次被调用时立即被处理。
比如:
observable.subscribeOnce(func);
在我的用例中,我在一个快速路由处理程序中创建了一个订阅,并且每个请求都被多次调用订阅。
不是100%确定你需要什么,但如果你只想观察第一个值,那么使用first()或take(1):
observable.first().subscribe(func);
注意:.take(1)和.first()都在满足条件时自动取消订阅
从RxJS 5.5+更新
来自Coderer的评论。
import { first } from 'rxjs/operators'
observable
.pipe(first())
.subscribe(func);
这是为什么
RxJS有一些我所见过的最好的文档。按照下面的链接,您将看到一个非常有用的表,将用例映射到操作符。例如,在“我想取第一个值”用例下有三个操作符:first、firstOrDefault和sample。
注意,如果一个可观察序列结束时没有通知,那么第一个操作符会通知订阅者一个错误,而firstOrDefault操作符则会向订阅者提供一个默认值。
操作符用例查找
为了补充@Brandon的回答,使用first()或类似的方法对于根据其Observable更新BehaviorSubject也是必不可少的。例如(未经测试):
var subject = new BehaviorSubject({1:'apple',2:'banana'});
var observable = subject.asObservable();
observable
.pipe(
first(), // <-- Ensures no stack overflow
flatMap(function(obj) {
obj[3] = 'pear';
return of(obj);
})
)
.subscribe(function(obj) {
subject.next(obj);
});
更新(2021年12月):
在RxJS 7中,promise()函数已经被弃用,新的函数已经被宣布用来代替它。firstValueFrom和lastValueFrom。
函数firstvaluefrom解析第一个发出的值,并直接从资源取消订阅。当Observable完成而没有释放任何值时,它会以EmptyError拒绝。
另一方面,lastValueFrom函数在某种程度上与toPromise()相同,因为它解析了可观察对象完成时发出的最后一个值。然而,如果该可观察对象没有发出任何值,它将拒绝一个EmptyError。不像toPromise(),当没有值发出时解析为undefined。
欲了解更多信息,请查看文档。
旧的回答:
如果你只想调用一个Observable一次,这意味着你不会等待来自它的流。所以使用toPromise()而不是subscribe()在你的情况下就足够了,因为toPromise()不需要取消订阅。
干净方便的版本
扩展M Fuat NUROĞLU关于将可观察对象转换为承诺的惊人答案,这里是它的非常方便的版本。
const value = await observable.toPromise();
console.log(value)
这样做的好处是,我们可以像使用普通变量一样使用该值,而无需引入另一个嵌套块!
当您需要从多个可观察对象中获取多个值时,这尤其方便。整洁干净。
const content = await contentObservable.toPromise();
const isAuthenticated = await isAuthenticatedObservable.toPromise();
if(isAuthenticated){
service.foo(content)
}
当然,如果你要走这条路,你必须让你的包含函数异步。如果你不希望包含函数是异步的,你也可以。then promise
我不确定这种方法是否有折衷之处,请在评论中告诉我,以便我们了解。
附注:如果你喜欢这个答案,别忘了给M Fuat NUROĞLU的答案投票:)
我也有类似的问题。
下面是稍后从不同的状态更改器调用的。因为我不想这么做。
function foo() {
// this was called many times which was not needed
observable.subscribe(func);
changeObservableState("new value");
}
我决定在订阅后尝试unsubscribe(),如下所示。
function foo() {
// this was called ONE TIME
observable.subscribe(func).unsubscribe();
changeObservableState("new value");
}
订阅(函数).unsubscribe ();类似于subscribeOnce(func)。
我希望这对你也有帮助。