如何在Angular中出错时取消Observable间隔

时间:2018-03-10 21:29:40

标签: angular observable

我在Angular 5应用程序中有一项服务,该应用程序定期轮询API以查看用户有多少通知:

public getRegularNotificationCountForUser(userid): Observable<number> {    
  return Observable.interval(5000)
    .switchMap(() => this.http.get<number>(this.baseUrl + '/getNotificationCountForUser?UserId=' + userid));
}

我从标题中的ngInit函数调用此服务:

ngOnInit() {
    this.notificationService.getRegularNotificationCountForUser(this.currentUser.id)
    .subscribe(result => {
        this.notificationsCount = result as number;
    });
}

我有两个问题:

  1. 如果API出错,我该如何阻止客户端轮询服务?如果我得到500,我想单独离开服务器,如果我得到401,我想确保前端记录用户。

  2. 这是正确的做法吗? API可以处理预期的负载,但这是否会导致客户端出现任何性能问题?

  3. 我非常感谢有关如何改进此代码的任何建议。

2 个答案:

答案 0 :(得分:2)

  

如果API出错,我该如何阻止客户端轮询服务?

HTTP错误将在observable中作为错误通知传播,switchMap也将传播。根据可观察的合同,这意味着订阅现已关闭;意思是结束民意调查你不必再做任何事了(如果我是你,我可能想要相反的 - 抓住错误并继续。你真的想要杀死民意调查,因为可能是临时网络问题?)

  

如果我得到500,我想单独离开服务器,如果我得到401,我想确保前端记录用户。

如果您希望错误传播,但无论如何都要对其做出反应,那么您可以使用subscribe的第二个参数:

obs$.subscribe(null, err => {
  if (err.status === 401) {
    this.userService.logOut();
  }
});
  

API可以处理预期的负载,但是这会导致客户端出现任何性能问题吗?

恕我直言,主要问题是你不是在等待回应;每5秒,您将开始一个新的请求。在慢速连接上,这意味着

  • 如果请求需要三秒钟才能返回,那么只有2s时间窗口没有请求正在进行。
  • 如果请求需要5秒或更长时间,您将从不获得响应,因为switchMap将取消之前的请求。

您可以使用mergeMap来处理第二个问题,但在响应和请求之间等待5秒通常更好,而不是在两个请求之间。

也就是说,如果可以使用像websockets这样的东西,那么你肯定会在使用它时获得更好的用户体验。由于防止了不必要的呼叫,并且数据被实时推送给用户而不是最多延迟5秒,因此负载将是最小的。

答案 1 :(得分:0)

如果从API中收到错误,则会调度错误抛出整个可观察链并取消源间隔。您可以在订阅中对此错误(句柄500或401)作出反应(第二个参数是错误回调)。

使用switchMap,如果在新来电时没有收到回复,则会取消之前的通话,因此我认为对于客户来说,处理的时间太重了。