【发布时间】:2017-11-11 20:37:31
【问题描述】:
我在下面创建了 Observable 构造函数,其工作方式与描述的一样。有谁知道使用 RxJs 附带的运算符是否有更简洁的方法来实现相同的行为?我正在查看bufferToggle,它接近所需的行为,但我需要在缓冲区关闭时传递发出的值。
函数说明:如果condition发出true,则缓冲发出的source值,如果condition发出false,则传递发出的source值。如果条件在true 之后发出false,则缓冲区会按照接收到的顺序释放每个值。缓冲区初始化为传递发出的source 值,直到condition 发出true。
function bufferIf<T>(condition: Observable<boolean>, source: Observable<T>): Observable<T> {
return new Observable<T>(subscriber => {
const subscriptions: Subscription[] = [];
const buffer = [];
let isBufferOpen = false;
subscriptions.push(
// handle source events
source.subscribe(value => {
// if buffer is open, or closed but buffer is still being
// emptied from previously being closed.
if (isBufferOpen || (!isBufferOpen && buffer.length > 0)) {
buffer.push(value);
} else {
subscriber.next(value);
}
}),
// handle condition events
condition.do(value => isBufferOpen = value)
.filter(value => !value)
.subscribe(value => {
while (buffer.length > 0 && !isBufferOpen) {
subscriber.next(buffer.shift());
}
})
);
// on unsubscribe
return () => {
subscriptions.forEach(sub => sub.unsubscribe());
};
});
}
编辑
作为对评论的回应,以下功能与上述功能相同,但采用 RxJs 运算符的形式,并更新为使用 RxJx 6+ pipeabale 运算符:
function bufferIf<T>(condition: Observable<boolean>): MonoTypeOperatorFunction<T> {
return (source: Observable<T>) => {
return new Observable<T>(subscriber => {
const subscriptions: Subscription[] = [];
const buffer: T[] = [];
let isBufferOpen = false;
subscriptions.push(
// handle source events
source.subscribe(value => {
// if buffer is open, or closed but buffer is still being
// emptied from previously being closed.
if (isBufferOpen || (!isBufferOpen && buffer.length > 0)) {
buffer.push(value);
} else {
subscriber.next(value);
}
}),
// handle condition events
condition.pipe(
tap(con => isBufferOpen = con),
filter(() => !isBufferOpen)
).subscribe(() => {
while (buffer.length > 0 && !isBufferOpen) {
subscriber.next(buffer.shift());
}
})
);
// on unsubscribe
return () => subscriptions.forEach(sub => sub.unsubscribe());
});
}
}
【问题讨论】:
-
是否有允许在管道中使用它的实现?在你通常会使用
buffer的地方 -
是的。请参阅上面的编辑。
-
谢谢你,你是救命稻草!如果我可以再次投票,我会:-)