Javascript RxJS - 发生错误时 observable 不会完成
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33783967/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
RxJS - observable doesn't complete when an error occurs
提问by Oved D
When I create an observable from scratch, and have the observer error, then complete, the done part of the subscription never is invoked.
当我从头开始创建一个 observable 并且有观察者错误,然后完成时,订阅的完成部分永远不会被调用。
var observer = Rx.Observable.create(function(observer){
observer.onError(new Error('no!'));
observer.onCompleted();
})
observer.subscribe(
function(x) { console.log('succeeded with ' + x ) },
function(x) { console.log('errored with ' + x ) },
function() { console.log('completed') }
)
The output is:
输出是:
errored with Error: no!
I'd expect it to be:
我希望它是:
errored with Error: no!
completed
If I change the code to invoke onNext instead of onError, the observable properly completes:
如果我更改代码以调用 onNext 而不是 onError,则 observable 会正确完成:
var observer = Rx.Observable.create(function(observer){
observer.onNext('Hi!');
observer.onCompleted();
})
observer.subscribe(
function(x) { console.log('succeeded with ' + x ) },
function(x) { console.log('errored with ' + x ) },
function() { console.log('completed') }
)
I get the expected output:
我得到预期的输出:
succeeded with Hi!
completed
Why does it not complete when an error has occured?
为什么发生错误时它没有完成?
回答by user3743222
That's because an error means completion, so the callback associated to onCompleted
never gets called. You can review here Rxjs contract for observables (http://reactivex.io/documentation/contract.html) :
那是因为错误意味着完成,因此onCompleted
永远不会调用关联的回调。您可以在此处查看可观察的 Rxjs 合同(http://reactivex.io/documentation/contract.html):
An Observable may make zero or more OnNext notifications, each representing a single emitted item, and it may then follow those emission notifications by either an OnCompleted or an OnError notification, but not both. Upon issuing an OnCompleted or OnError notification, it may not thereafter issue any further notifications.`
一个 Observable 可以发出零个或多个 OnNext 通知,每个通知代表一个发出的项目,然后它可以通过 OnCompleted 或 OnError 通知来跟随这些发出通知,但不能同时进行。在发出 OnCompleted 或 OnError 通知后,它可能不会发出任何进一步的通知。`
For error management, you can have a look at : https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/errors.md
对于错误管理,您可以查看:https: //github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/errors.md
回答by coni2k
While I was having the same question, I bumped into this github issue.
当我有同样的问题时,我遇到了这个github 问题。
Apparently finally
method of Observable
object needs to be used in this case.
显然在这种情况下需要使用 object 的finally
方法Observable
。
Quoting from Aleksandr-Leotech from that thread:
从该线程中引用 Aleksandr-Leotech:
Complete and finally are totally different things. Complete means that the observable steam was finished successfully. Because you can have many success calls. Finally means that steam has ended, either successfully or not.
It is not obvious with HTTP requests, but imagine two additional scenarios.
Mouse events. You will be receiving a never-ending steam of success callbacks, but you will never receive finally or complete, because user events will never stop (unless you trigger an exception with buggy code, then you will get error and finally).
Working with web sockets. You will get multiple success callbacks, but at some point in time your communication with back end will stop and you will get both complete and finally unless you have some errors, which will call error and finally.
So, you might be getting multiple or no success calls, zero or one error call, zero or one complete and zero or one finally.
Complete 和 finally 是完全不同的东西。Complete 表示可观察到的蒸汽已成功完成。因为你可以有很多成功的电话。最后意味着蒸汽已经结束,无论成功与否。
HTTP 请求并不明显,但可以想象另外两个场景。
鼠标事件。您将收到永无止境的成功回调流,但您永远不会收到 finally 或 complete,因为用户事件永远不会停止(除非您使用错误代码触发异常,否则您将收到错误并最终)。
使用网络套接字。您将获得多个成功回调,但在某个时间点,您与后端的通信将停止,除非您有一些错误,否则您将获得 complete 和 finally,这将调用 error 和 finally。
因此,您可能会收到多个成功调用或没有成功调用、零个或一个错误调用、零个或一个完整调用以及零个或一个最终调用。
回答by Just Shadow
Another and probably the simplest solution might be using add()
function.
In this case the statement will be always executed regardless error occured
or call succeded (alike finally
in most programming languages).
另一个可能是最简单的解决方案可能是使用add()
函数。
在这种情况下,无论发生错误还是调用成功,语句都将始终执行(finally
在大多数编程语言中)。
observer.subscribe(
function(x) { console.log('succeeded with ' + x ) },
function(x) { console.log('errored with ' + x ) },
function() { console.log('completed') }
)
.add(() => {
console.log("Will be executed on both success or error of the previous subscription")
);