如何解决当 observable 完成时,我应该如何发出单个值?
我想在原始 observable 完成时发出一个值,让我们说如下,使用虚运算符 mapComplete
:
let arr = ['a','b','c'];
from(arr)
.pipe(mapComplete(()=>'myValue'))
.pipe(map((v)=>`further processed: ${v}`))
.subscribe(console.log)
//further processed: myValue
我尝试了以下工作但似乎不合适的方法:
1.
from(arr)
.pipe(toArray())
.pipe(map(()=>'myValue'))
.pipe(map((v)=>`further processed: ${v}`))
.subscribe(console.log);
//further processed: myValue
问题:如果原始 observable 是一个巨大的流,我不想将它缓冲到一个数组,只是为了发出一个值。
2.
from(arr)
.pipe(last())
.pipe(map(()=>'myValue'))
.pipe(map((v)=>`further processed: ${v}`))
.subscribe(console.log);
//further processed: myValue
问题:如果流完成而没有发出任何内容,我会收到一个错误:[Error [EmptyError]: no elements in sequence]
执行上述操作的正确方法(在 rxjs 中)是什么?
解决方法
您可以使用 ignoreElements
不发出任何内容并使用 endWith
在完成时发出值来实现这一点。
from(arr).pipe(
ignoreElements(),endWith('myValue'),map(v => `further processed: ${v}`)
).subscribe(console.log);
如果您想在 map
中执行一个函数,您可以预先使用 count()
在完成时发出一个值(发出的值的数量)。
from(arr).pipe(
count(),// could also use "reduce(() => null,0)" or "last(null,0)" or "takeLast(1),defaultIfEmpty(0)"
map(() => getMyValue()),map(v => `further processed: ${v}`)
).subscribe(console.log);
,
您可以通过构建自己的自定义运算符来实现您想要的。
代码看起来像这样
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();
},});
});
基本上这个操作符会接收源 observable,忽略它发出的所有值,并且只在源完成时发出。
您可以查看 this stackblitz 进行一些测试。
,您还可以使用带有默认值的 last()
运算符。当流为空时,它将删除 no elements in sequence
错误。
from(arr).pipe(
last(null,'myValue'),// `null` denotes no predicate
map(_ => 'myValue'),// map the last value from the stream
map((v)=>`further processed: ${v}`)
).subscribe(console.log);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。