我正在创建一个使用RxJS Observable的模块,并且某些方法返回org.eclipse.search2.internal.ui.SearchView
。我已经搜索了很多,但是在完成org.eclipse.ui.internal.console.ConsoleView
时找不到任何最佳做法。
所以问题很简单,应该为这些可观察对象发出Observable<void>
回调,还是仅发出Observable<void>
回调?
在我看来,仅调用next
似乎是最干净的方法,但是complete
的最后一个参数是complete
,这使用户使用起来更加复杂。
以该代码示例作为问题的说明:
Observable<T>.subscribe()
答案 0 :(得分:2)
就个人而言,我的方法是,如果您拥有Observable<void>
,则表示它发出了,但其值无关紧要。您仍然可以调用next()
,但是为了使您清楚地知道没有传递任何值,您应该使用void 0
:
subject.next(void 0);
然后,就像在其他Observable中使用此Subject一样,只需忽略值本身即可:
subject.subscribe(() => ...);
这里重要的是,这与使用null
或undefined
不同。例如,您可以使用Observable<number>
并调用observer.next(null)
或observer.next(undefined)
(https://stackblitz.com/edit/rxjs6-demo-jtwymx?file=index.ts),即使这没有任何意义。您想要number
,但是如果收到undefined
,则可能会遇到奇怪的行为。例如undefined + 4
是NaN
。
我认为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()
!