Rxjs 当observable完成时,我应该如何发出单个值?

Rxjs 当observable完成时,我应该如何发出单个值?,rxjs,observable,rxjs6,Rxjs,Observable,Rxjs6,我想在原始可观测对象完成时发出一个值,比如下面,使用虚拟操作符mapComplete: 让arr=['a','b','c']; 从(arr) .pipe(映射完成(()=>'myValue')) .pipe(map((v)=>`进一步处理:${v}`) .subscribe(console.log) //进一步处理:myValue 我尝试了以下方法,但似乎不合适: 1. from(arr) .管道(toArray()) .pipe(映射(()=>'myValue')) .pipe(map((v

我想在原始可观测对象完成时发出一个值,比如下面,使用虚拟操作符
mapComplete

让arr=['a','b','c'];
从(arr)
.pipe(映射完成(()=>'myValue'))
.pipe(map((v)=>`进一步处理:${v}`)
.subscribe(console.log)
//进一步处理:myValue
我尝试了以下方法,但似乎不合适:

1.

from(arr)
.管道(toArray())
.pipe(映射(()=>'myValue'))
.pipe(map((v)=>`进一步处理:${v}`)
.subscribe(console.log);
//进一步处理:myValue
问题:如果原始可观察对象是一个巨大的流,我不想将其缓冲到数组中,只想发出一个值

2.

from(arr)
.pipe(最后一个())
.pipe(映射(()=>'myValue'))
.pipe(map((v)=>`进一步处理:${v}`)
.subscribe(console.log);
//进一步处理:myValue
问题:如果流完成时没有发出任何信息,我会得到一个错误:
[错误[EmptyError]:序列中没有元素]


做上述工作的正确方法是什么(用rxjs术语)?

您可以通过构建自己的自定义操作符来实现您想要的

代码可能是这样的

const emitWhenComplete = <T>(val: T) => <U>(source: Observable<U>) =>
  new Observable<T>((observer) => {
    return source.subscribe({
      error: (err) => observer.error(err),
      complete: () => {
        observer.next(val);
        observer.complete();
      },
    });
  });
const emitWhenComplete=(val:T)=>(来源:可观测)=>
新可观察((观察者)=>{
返回source.subscribe({
错误:(err)=>观察者错误(err),
完成:()=>{
观察员:下一个(val);
observer.complete();
},
});
});
基本上,这个操作符将接收可观察的源,忽略它发出的所有值,并且仅在源完成时发出

您可以查看一些测试。

您可以通过不发射任何东西和在完成时发射值来实现这一点

from(arr).管道(
ignoreElements(),
以('myValue')结尾,
映射(v=>`进一步处理:${v}`)
).subscribe(console.log);
如果要在
map
中执行一个函数,可以事先使用在完成时发出一个值(发出的值的数量)

from(arr).管道(
count(),//也可以使用“reduce(()=>null,0)”或“last(null,0)”或“takeLast(1),defaultIfEmpty(0)”
映射(()=>getMyValue()),
映射(v=>`进一步处理:${v}`)
).subscribe(console.log);

您还可以使用带有默认值的
last()
运算符。当流为空时,它将删除序列中的
no元素
错误

from(arr).管道(
last(null,'myValue'),//'null'表示没有谓词
map(=>'myValue'),//映射流中的最后一个值
map((v)=>`进一步处理:${v}`)
).subscribe(console.log);

last(null,'myValue')
如果
from(arr)
发出某些信息,则不会将
myValue
作为最后一个值发出。因此,如果
from(arr)
发出任何信息,您仍然需要使用
map(()=>'myValue')
@fridoo将其最后一个值映射到
myValue
。谢谢,回答得好。注意:为了完整性,由于虚构的
mapComplete()
接受lambda,因此最好提供一个计算排放时值的解决方案。我想一张额外的地图就可以解决这个问题,但也许还有其他的解决办法。@MarinosAn是的,你可以在
endWith
之后使用
map
。我能想到的另一个更短的选项是
count
before
map
。还有一些方法可以替代
count
,但正如你在我的编辑中看到的那样,它们都很长。我想答案现在已经完成了!