Rxjs &引用;簿记结束“;来自可观测源的值

Rxjs &引用;簿记结束“;来自可观测源的值,rxjs,Rxjs,我想“bookend”一条流中的值。更具体地说,来自这样一个来源 从“rxjs”导入{of}; 让开始$=of(1,2,3); 我想要一个可以观察到的 // 1-enter // 1 // 1-exit // 2-enter // 2 // 2-exit // 3-enter // 3 我可以在中间添加一个主题,例如:。 从“rxjs”导入{of,Subject}; 从“rxjs/operators”导入{startWith,成对,delay}; 让start$=of(1,2,3).pipe

我想“bookend”一条流中的值。更具体地说,来自这样一个来源

从“rxjs”导入{of};
让开始$=of(1,2,3);
我想要一个可以观察到的

// 1-enter
// 1
// 1-exit
// 2-enter
// 2
// 2-exit
// 3-enter
// 3
我可以在中间添加一个主题,例如:

从“rxjs”导入{of,Subject};
从“rxjs/operators”导入{startWith,成对,delay};
让start$=of(1,2,3).pipe(delay(1000));
函数createBookendedStream(开始$){
让输入$=start$.pipe(startWith(未定义),成对();
让输出$=新主题();
输入$.subscribe(函数([prev,curr]){
如果(上一个)输出$.next(上一个+“-退出”);
输出$.next(当前+“-输入”);
输出$.next(货币);
});
返回输出$;
}
createBookendedStream(start$).subscribe(console.log);
这和我预期的完全一样,但感觉有点粗糙。我觉得我错过了什么。是否有更规范的方法,例如使用运算符


谢谢

您想要的是一种很好的方法,将每个元素映射到一个倍数,然后将结果平坦化为一个可观察值(听起来像是
flatMap
*!):

const bookend$=start$.pipe(
平面图(el=>from([$'{el}-enter',el,$'{el}-exit']))
);
但是
flatMap
不能保证每个子序列都会按顺序完全展平,而不会在前面的“退出”之前将“进入”合并到一起(我认为在您的情况下,它会起作用,因为不涉及任意延迟或计时,但我不能100%确定)

concatMap
保证您的行为井然有序,但由于它必须维护一个缓冲区,因此增加内存使用的成本(可能微不足道):

const bookend$=start$.pipe(
concatMap(el=>from([$'{el}-enter',el,$'{el}-exit']))
);

*也被称为它的别名
mergeMap

,我想你说得很好。我不认为
flatMap
会发出无序的信号,但为了澄清意图,我会选择
concatMap
,因为这表明顺序很重要。