在我的Angular应用程序中,我处理通知,并且我有一个REST API来调用最新用户的通知。我需要在几分钟内调用此API,因为用户实时收到通知并不是很重要(他们可能甚至不会出现这么快)。但是,下一步是在客户端刷新通知的想法:
我已经有了所描述程序的工作代码,但我不确定它是否符合我的要求。以下是执行调用的代码(对于手动检查,只有一个主题,并且对于停止检查,存在对可观察的订阅 - 下面的代码实际上是分开的,但由于可读性,这里在一个地方):
// Subject for manual triggering
this.checkFeed = new Subject<void>();
// Call for refresh in own method
this.checkFeed.next();
// Waiting for manual refresh or triggering it on some interval after it was last triggered
this.feedSub = this.checkFeed.asObservable()
.switchMap(() => Observable.timer(0, this.interval))
.mergeMap(() => this.fetchChanges())
.distinctUntilChanged(this.compareFeed)
.subscribe(res => this.notify(res));
// Unsubscription when logging out
if (this.feedSub) this.feedSub.unsubscribe();
我最不确定的部分是.switchMap(() => Observable.timer(0, this.interval))
,因为它需要0
立即开始(这没关系,但仍然看起来不正确?) 。那么有没有更好的方法来实现我所描述的呢?
我还有另一个问题,如何开始检查来自另一个observable的通知 - 我应该使用哪个运算符。正如我所提到的,我已经用自己的方法调用了下一个主题:
refreshFeed(): void {
this.checkFeed.next();
}
所以当有一些其他可观察的表演时(通知应该被刷新的动作)我需要调用这个。当其他observable响应API时,调用void
方法的正确方法是什么?我在考虑这样的事情:
someActionThatCanChangeNotifications(): Observable<any> {
return this.api.get('path/to/endpoint')
.do(() => this.feedService.refreshFeed());
}
这样可以,还是有更好的方法?
提前感谢您的帮助!
答案 0 :(得分:0)
所以基本上你有两个可观察的。
您手动调用的一个:
this.checkFeed
和间隔(让我们的callit intervalObs):
this.intervalObs = Observable.timer(0, this.interval);
如果您这样看,最简单的方法是合并您的两个源流,然后做任何您想做的事。
var mergedSource = Observable.merge(
this.checkFeed,
this.intervalObs)
subscription = mergedSource.subscribe(this.fetchChanges());
也许您需要在两者之间进行更多操作,但这应该会为您提供更具可读性的替代方案。
如果你想要玩一些https://plnkr.co/edit/n4nNFEMa4YOh2KSjDpSJ?p=preview
的东西,你可以试试这个工作的plunker答案 1 :(得分:0)
从我所看到的你已经“正确地”完成了它。与一般的编程一样,单个问题有许多可能的(和正确的)解决方案。我个人也这样做。
我可以就你提到的两点给你一些评论:
.switchMap(() => Observable.timer(0, this.interval))
Observable.timer
几乎是Observable.interval
,在第一个值之前有自定义超时。 Observable.timer(0, this.interval)
是正确的用法。
替代方案可以是Observable.just(0).concat(Observable.interval(this.interval))
,它会立即返回一个值,然后开始间隔。我更喜欢你的方式;我认为它清楚地表明了你的意图:“在0
毫秒之后产生一个值,然后产生this.interval
”的间隔。
.do(() => this.feedService.refreshFeed())
我认为这是完全正确的做法。 do
用于副作用,例如。发生在外面可观察物的东西。
我可以说,我不希望someActionThatCanChangeNotifications
开始刷新Feed。当一个函数返回一个observable时,我希望返回一个没有任何副作用的observable。然而,当我们生活在一个不完美的世界时,我们不能总是拥有我们想要的东西。
你不能指望每个订阅者都记得做.do(() => this.feedService.refreshFeed())
,而是在函数的doc注释中添加一个通知:“注意:返回的observable将刷新每个下一个信号的feed”或者那种东西。