共享源并在订阅时重播指定数量的发出。
构造函数
shareReplay<T>(configOrBufferSize?: number | ShareReplayConfig, windowTime?: number, scheduler?: SchedulerLike): MonoTypeOperatorFunction<T>
参数
参数 | 说明 |
---|---|
configOrBufferSize | 可选。默认为undefined 。类型: number | ShareReplayConfig |
windowTime | 可选。默认为undefined 。重播缓冲区的最大时间长度(毫秒)。 |
scheduler | 可选。默认为undefined 。调度程序,选择器函数中连接的观察程序将在其中调用。 |
返回
MonoTypeOperatorFunction<T>
: 返回一个Observable序列的函数,包含在选择器函数中对源序列进行多播产生的序列元素。
描述
这个操作符是replay
的一个专门化,它通过一个用指定参数构造的ReplaySubject
连接到一个可观察的源和多播。成功完成的源将永远缓存在shareReplayed observable
中,但出错的源可以重试。
为什么要使用shareReplay
当你不希望在多个subscribers之间执行副作用或繁重的计算时,通常希望使用shareReplay。它也可能很有用的,当你知道你将有对于一个流的延迟的订阅者需要访问先前提交的值。这种在订阅上重播值的能力是share
和shareReplay
的区别。
参考计数
从RXJS版本6.4.0开始,添加了一个新的重载签名,以允许手动控制当操作员内部参考计数器降为零时发生的情况。如果refCount
为true,则一旦引用计数降至零,源将取消订阅,即内部ReplaySubject将取消订阅。所有新的订户都将从一个新的ReplaySubject
接收值发射,这反过来又将导致对可观测源的新订阅。另一方面,如果refCount
为false,则源将不会取消订阅,这意味着内部ReplaySubject
仍将订阅源(并且可能永远运行)。
例如:
import { interval } from 'rxjs';
import { shareReplay, take } from 'rxjs/operators';
const obs$ = interval(1000);
const shared$ = obs$.pipe(
take(4),
shareReplay(3)
);
shared$.subscribe(x => console.log('sub A: ', x));
shared$.subscribe(y => console.log('sub B: ', y));
refCount
使用的例子:
import { interval, Observable, defer } from 'rxjs';
import { shareReplay, take, tap, finalize } from 'rxjs/operators';
const log = <T>(source: Observable<T>, name: string) => defer(() => {
console.log(`${name}: subscribed`);
return source.pipe(
tap({
next: value => console.log(`${name}: ${value}`),
complete: () => console.log(`${name}: complete`)
}),
finalize(() => console.log(`${name}: unsubscribed`))
);
});
const obs$ = log(interval(1000), 'source');
const shared$ = log(obs$.pipe(
shareReplay({bufferSize: 1, refCount: true }),
take(2),
), 'shared');
shared$.subscribe(x => console.log('sub A: ', x));
shared$.subscribe(y => console.log('sub B: ', y));
// PRINTS:
// shared: subscribed <-- reference count = 1
// source: subscribed
// shared: subscribed <-- reference count = 2
// source: 0
// shared: 0
// sub A: 0
// shared: 0
// sub B: 0
// source: 1
// shared: 1
// sub A: 1
// shared: complete <-- take(2) completes the subscription for sub A
// shared: unsubscribed <-- reference count = 1
// shared: 1
// sub B: 1
// shared: complete <-- take(2) completes the subscription for sub B
// shared: unsubscribed <-- reference count = 0
// source: unsubscribed <-- replaySubject unsubscribes from source observable because the reference count dropped to 0 and refCount is true
// In case of refCount being false, the unsubscribe is never called on the source and the source would keep on emitting, even if no subscribers
// are listening.
// source: 2
// source: 3
// source: 4
// ...