可观察的最终订阅

根据 这篇文章subscribeonCompleteonError功能是相互排斥的。

这意味着 onError或者 onComplete事件将在我的 subscribe中启动。
我有一个逻辑块需要执行,无论我收到一个错误,或我完成我的信息蒸汽成功。

我寻找类似于 蟒蛇中的 finally的东西,但是我发现的只是 finally,它需要连接到我创建的可观察的东西上。

但是我希望只在我订阅时和流结束后执行这个逻辑,无论是成功还是出错。

有什么想法吗?

151119 次浏览

这个操作符的当前“可管”变体称为 finalize()(自 RxJS6以来)。旧的、现在已经废弃的“补丁”操作符称为 finally()(直到 RxJS 5.5)。

我认为 finalize()操作员实际上是正确的。你说:

只有当我订阅,并在流结束后,才进行这种逻辑

我觉得这不是问题。您可以有一个单一的 source和使用 finalize()之前,订阅它,如果你想要的。这样你就不需要使用 一直都是了:

let source = new Observable(observer => {
observer.next(1);
observer.error('error message');
observer.next(3);
observer.complete();
}).pipe(
publish(),
);


source.pipe(
finalize(() => console.log('Finally callback')),
).subscribe(
value => console.log('#1 Next:', value),
error => console.log('#1 Error:', error),
() => console.log('#1 Complete')
);


source.subscribe(
value => console.log('#2 Next:', value),
error => console.log('#2 Error:', error),
() => console.log('#2 Complete')
);


source.connect();

这将打印到控制台:

#1 Next: 1
#2 Next: 1
#1 Error: error message
Finally callback
#2 Error: error message

2019年1月: 为 RxJS 6更新

我现在在一个 Angular 应用程序中使用 RxJS5.5.7,使用 finalize操作符对于我的用例有一个奇怪的行为,因为它在成功或错误回调之前被触发。

举个简单的例子:

// Simulate an AJAX callback...
of(null)
.pipe(
delay(2000),
finalize(() => {
// Do some work after complete...
console.log('Finalize method executed before "Data available" (or error thrown)');
})
)
.subscribe(
response => {
console.log('Data available.');
},
err => {
console.error(err);
}
);

我不得不在订阅中使用 add方法来完成我想要的。基本上是在成功或错误回调完成之后的 finally回调。类似于 try..catch..finally块或 Promise.finally方法。

举个简单的例子:

// Simulate an AJAX callback...
of(null)
.pipe(
delay(2000)
)
.subscribe(
response => {
console.log('Data available.');
},
err => {
console.error(err);
}
)
.add(() => {
// Do some work after complete...
console.log('At this point the success or error callbacks has been completed.');
});

唯一对我有用的就是这个

fetchData()
.subscribe(
(data) => {
//Called when success
},
(error) => {
//Called when error
}
).add(() => {
//Called when operation is complete (both success and error)
});