在RxJS中的Observable <void>上调用observer.next()

时间:2018-07-12 20:47:49

标签: angular rxjs

我正在创建一个使用RxJS Observable的模块,并且某些方法返回org.eclipse.search2.internal.ui.SearchView。我已经搜索了很多,但是在完成org.eclipse.ui.internal.console.ConsoleView时找不到任何最佳做法。

所以问题很简单,应该为这些可观察对象发出Observable<void>回调,还是仅发出Observable<void>回调?

在我看来,仅调用next似乎是最干净的方法,但是complete的最后一个参数是complete,这使用户使用起来更加复杂。

以该代码示例作为问题的说明:

Observable<T>.subscribe()

2 个答案:

答案 0 :(得分:2)

就个人而言,我的方法是,如果您拥有Observable<void>,则表示它发出了,但其值无关紧要。您仍然可以调用next(),但是为了使您清楚地知道没有传递任何值,您应该使用void 0

subject.next(void 0);

然后,就像在其他Observable中使用此Subject一样,只需忽略值本身即可:

subject.subscribe(() => ...);

这里重要的是,这与使用nullundefined不同。例如,您可以使用Observable<number>并调用observer.next(null)observer.next(undefined)https://stackblitz.com/edit/rxjs6-demo-jtwymx?file=index.ts),即使这没有任何意义。您想要number,但是如果收到undefined,则可能会遇到奇怪的行为。例如undefined + 4NaN

我认为Observable<void>的典型用例是无限滚动。当您滚动到页面的末尾时,您希望加载更多数据,因此您可以调用subject.next(void 0),在该位置显然值无关紧要。它仅用于触发加载更多项目。

答案 1 :(得分:0)

当您要响应可能更改的数据流时,可以使用Observable。您上面的函数doSomethingIgnoreUnlessError()将返回给您一个可观察的对象,您可以使用回调函数将其.subscribe()返回给您;该函数将在Observable每次调用.next()时执行。对于Observable<void>,您可以像这样在subscribe回调中省略数据有效载荷函数参数:

doSomethingIgnorableUnlessError().subscribe(() => {
    // do something; without data it's just an event
}).catch(err => {
    // handle error condition from returned Observable
});

最终,您至少需要调用.next()一次,以便该可观察对象的任何订阅者都可以接收该事件并触发.subscribe()。使用.complete()会产生另一个事件,该事件可以与返回的Observable挂钩,并且不支持传递任何数据。所以它或多或少是您响应的事件。

我们可以使用.subscribe()方法的可选参数来说明和简化此过程,如下所示:

doSomethingIgnorableUnlessError().subscribe(() => {
    // do something; without data it's just an event
}, err => {
    // handle error condition from returned Observable
}, () => {
    // handle subscription complete (no more data coming)
});

这将捕获所有三个-订阅数据,错误和完成事件。 如果您从不在Observable中调用.next(),则订阅回调(第一个参数)将永远不会触发,并且编写仅发送完成事件的Observable有点不直观。如果这是您的需要,并且必须使用Observable,则建议将其转换为始终一次性使用的Promise。甚至有.toPromise()内置的设备可以满足这种情况!

所以 TL; DR -如果忽略将数据传递到null的情况,将.next()传递给.subscribe()并不重要所返回的Observable中的一个,如果您想终止数据流并取消所有订阅,则只能在Observable中手动调用.complete()。如果您的Observable仍然需要推送其他更改值,请不要调用.complete()