Angular 2+ 使用 RxJS - 完成与退订关于 take(1) 和 first()
Angular 2+ using RxJS - complete vs unsubscribe regarding take(1) and first()
通读了一些文档和问题,我发现使用 first() 或 take(1) 时有点不清楚天气实际上在完成时退订。我想我的困惑是围绕 'complete' 与 'unsubscribe'。说一个 observable 完成,这是否也意味着订阅被取消订阅?我正在考虑这个用于垃圾收集,而我需要知道可观察对象在 first() 或 take(1) 完成后不保留任何引用。
如果这些功能不取消订阅,我需要知道最简单的完成后取消订阅的方法。或者这甚至是必要的?
源代码中的一些内容,
(do) first() and take(1) actually unsubscribe when they complete
看起来是这样。
take.ts
protected _next(value: T): void {
const total = this.total;
const count = ++this.count;
if (count <= total) {
this.destination.next(value);
if (count === total) {
this.destination.complete();
this.unsubscribe();
}
}
}
To say an observable completes, does that also mean the subscriptions are unsubscribed?
在 Subscription.ts 中遇到了这个(在文档中没有看到)
/**
* Adds a tear down to be called during the unsubscribe() of this
* Subscription.
*
...
*/
add(teardown: TeardownLogic): Subscription {
所以我认为拆解可以用来验证是否调用了取消订阅。
const source1 = Observable.range(1, 10).take(6)
const subscription1 = source1.subscribe(x => console.log('subscription1'))
.add(() => console.log('teardown1'))
// Emits 6x then 'teardown1'
const subscription2 = source1.take(4).subscribe(x => console.log('subscription2'))
.add(() => console.log('teardown2'))
// Emits 4x then 'teardown2'
但请注意,take()
只会取消订阅其自身的下游,而不是 所有 订阅者取消订阅 observable
const source2 = Observable.range(1, 10)
const subscription3 = source2.subscribe(x => console.log('subscription3'))
.add(() => console.log('teardown3'))
// Emits 10x then 'teardown3'
const subscription4 = source2.take(5).subscribe(x => console.log('subscription4'))
.add(() => console.log('teardown4'))
// Emits 5x then 'teardown4'
I need to know that the observable isn't retaining any references after first() or take(1) complete.
这有点棘手,这里是Observable.subscribe()
方法。似乎观察者没有保留对其三个参数中任何一个的引用,而是订阅保留了对可观察对象的引用。
subscribe(observerOrNext?: PartialObserver<T> | ((value: T) => void),
error?: (error: any) => void,
complete?: () => void): Subscription {
const { operator } = this;
const sink = toSubscriber(observerOrNext, error, complete);
if (operator) {
operator.call(sink, this.source);
} else {
sink.add(this.source ? this._subscribe(sink) : this._trySubscribe(sink));
}
if (sink.syncErrorThrowable) {
sink.syncErrorThrowable = false;
if (sink.syncErrorThrown) {
throw sink.syncErrorValue;
}
}
return sink;
}
这可以在下面的测试代码中看到。当订阅处于活动状态(关闭:false)时,订阅者具有 _subscriptions
中引用的可观察对象
const source3 = Observable.interval(1000)
const subscription5 = source3.subscribe(x => {})
console.log(source3)
console.log(subscription5)
控制台输出:
IntervalObservable
period: 1000
scheduler: AsyncScheduler {...}
_isScalar: false
__proto__: Observable
Subscriber
closed: false
destination: SafeSubscriber {...}
isStopped: false
syncErrorThrowable: false
syncErrorThrown: false
syncErrorValue: null
_parent: null
_parents: null
_subscriptions: [AsyncAction]
__proto__: Subscription
但是当我们用 take(1)
、
关闭订阅时
const source3 = Observable.interval(1000).take(1)
const subscription5 = source3.subscribe(x => {})
console.log(source3)
console.log(subscription5)
订户_subscriptions
设置为空,释放引用。
Subscriber
closed: true
destination: SafeSubscriber {...}
isStopped: true
syncErrorThrowable: false
syncErrorThrown: false
syncErrorValue: null
_parent: null
_parents: null
_subscriptions: null
__proto__: Subscription
我不确定这是否可以被视为所有 observable/operator/subscriber 链的最终证明,但至少表明了一种验证您的特定用例的方法。
通读了一些文档和问题,我发现使用 first() 或 take(1) 时有点不清楚天气实际上在完成时退订。我想我的困惑是围绕 'complete' 与 'unsubscribe'。说一个 observable 完成,这是否也意味着订阅被取消订阅?我正在考虑这个用于垃圾收集,而我需要知道可观察对象在 first() 或 take(1) 完成后不保留任何引用。
如果这些功能不取消订阅,我需要知道最简单的完成后取消订阅的方法。或者这甚至是必要的?
源代码中的一些内容,
(do) first() and take(1) actually unsubscribe when they complete
看起来是这样。
take.ts
protected _next(value: T): void {
const total = this.total;
const count = ++this.count;
if (count <= total) {
this.destination.next(value);
if (count === total) {
this.destination.complete();
this.unsubscribe();
}
}
}
To say an observable completes, does that also mean the subscriptions are unsubscribed?
在 Subscription.ts 中遇到了这个(在文档中没有看到)
/**
* Adds a tear down to be called during the unsubscribe() of this
* Subscription.
*
...
*/
add(teardown: TeardownLogic): Subscription {
所以我认为拆解可以用来验证是否调用了取消订阅。
const source1 = Observable.range(1, 10).take(6)
const subscription1 = source1.subscribe(x => console.log('subscription1'))
.add(() => console.log('teardown1'))
// Emits 6x then 'teardown1'
const subscription2 = source1.take(4).subscribe(x => console.log('subscription2'))
.add(() => console.log('teardown2'))
// Emits 4x then 'teardown2'
但请注意,take()
只会取消订阅其自身的下游,而不是 所有 订阅者取消订阅 observable
const source2 = Observable.range(1, 10)
const subscription3 = source2.subscribe(x => console.log('subscription3'))
.add(() => console.log('teardown3'))
// Emits 10x then 'teardown3'
const subscription4 = source2.take(5).subscribe(x => console.log('subscription4'))
.add(() => console.log('teardown4'))
// Emits 5x then 'teardown4'
I need to know that the observable isn't retaining any references after first() or take(1) complete.
这有点棘手,这里是Observable.subscribe()
方法。似乎观察者没有保留对其三个参数中任何一个的引用,而是订阅保留了对可观察对象的引用。
subscribe(observerOrNext?: PartialObserver<T> | ((value: T) => void),
error?: (error: any) => void,
complete?: () => void): Subscription {
const { operator } = this;
const sink = toSubscriber(observerOrNext, error, complete);
if (operator) {
operator.call(sink, this.source);
} else {
sink.add(this.source ? this._subscribe(sink) : this._trySubscribe(sink));
}
if (sink.syncErrorThrowable) {
sink.syncErrorThrowable = false;
if (sink.syncErrorThrown) {
throw sink.syncErrorValue;
}
}
return sink;
}
这可以在下面的测试代码中看到。当订阅处于活动状态(关闭:false)时,订阅者具有 _subscriptions
const source3 = Observable.interval(1000)
const subscription5 = source3.subscribe(x => {})
console.log(source3)
console.log(subscription5)
控制台输出:
IntervalObservable
period: 1000
scheduler: AsyncScheduler {...}
_isScalar: false
__proto__: Observable
Subscriber
closed: false
destination: SafeSubscriber {...}
isStopped: false
syncErrorThrowable: false
syncErrorThrown: false
syncErrorValue: null
_parent: null
_parents: null
_subscriptions: [AsyncAction]
__proto__: Subscription
但是当我们用 take(1)
、
const source3 = Observable.interval(1000).take(1)
const subscription5 = source3.subscribe(x => {})
console.log(source3)
console.log(subscription5)
订户_subscriptions
设置为空,释放引用。
Subscriber
closed: true
destination: SafeSubscriber {...}
isStopped: true
syncErrorThrowable: false
syncErrorThrown: false
syncErrorValue: null
_parent: null
_parents: null
_subscriptions: null
__proto__: Subscription
我不确定这是否可以被视为所有 observable/operator/subscriber 链的最终证明,但至少表明了一种验证您的特定用例的方法。