如何删除Observable

时间:2016-10-18 12:08:18

标签: angular typescript rxjs5

Observable.timer(0, 1000)的帮助下,我按照定义的时间模式向我的服务器发出连续请求。在我处理了响应的内容后,可以在特殊条件下和取决于之前的响应我需要删除响应,因此不会将其传递给服务的订阅者:

@Injectable()
export class LoggerService {
  constructor(private http: Http) { }
  private apiURL = 'assets/file.json'; 

  getList() {
    return Observable.timer(0, 1000)
      .concatMap(() => this.http.get(this.apiURL))
      .map(this.extractData)
      .catch(this.handleError););
  }
  private extractData(res: Response) {
    var fooot = new Foo();
    fooot.fillFromJSON(JSON.stringify(res.json()));
    if(fooot.getProperty()){
    //DROP IT
    }
    return fooot;
  }

  private handleError(error: any) {
    let errMsg = (error.message) ? error.message :
      error.status ? `${error.status} - ${error.statusText}` : 'Server error';
    console.error(errMsg);
    return Observable.throw(errMsg);
  }
}

然后从组件的getList()调用ngOnInit方法。 目前我可以想到两种可能的解决方案,购买可能有更好/更清晰的方法来解决这个问题:

  1. 如果我必须删除响应,我会创建一个特殊对象,该对象由getList()的订阅者识别,然后专门处理。但是这个解决方案会非常难看,因为丢弃的响应会离开我的服务,我需要在服务之外额外编写代码来处理这种情况。

  2. 我必须放弃响应时抛出异常。然后捕获,识别异常(与其他情况不同),然后在没有任何通知/输出的情况下丢弃异常。然后重新启动observable。这种方法的优点是应该删除的observable不会离开服务,但我不喜欢在这种情况下对控制流使用异常。

  3. 我尝试了两种解决方案并且它们正在运行,但我希望有更好的方法。

2 个答案:

答案 0 :(得分:1)

如果我理解正确,您正在寻找switchMap运营商。

如果在1秒内没有响应到达(指定的时间间隔),则会以静默方式取消HTTP请求,并启动另一个请求。

更新

如果您要手动取消HTTP请求,则必须创建cancelSubject: Subject并在HTTP请求上定义takeUntil(cancelSubject)

要取消HTTP请求,只需拨打cancelSubject.next(true),然后取消HTTP请求,因为takeUntil生效。

请记住,一秒钟后,请求将重新启动。如果要取消计时器,则必须将.takeUntil(cancelSubject)放在外部可观察对象上。

答案 1 :(得分:1)

我最终使用distinctUntilChanged归档了我的目标:

getList() {
    return Observable.timer(0, 1000)
      .concatMap(() => this.http.get(this.apiURL)
      .distinctUntilChanged(null, x => x.json().info[1].value)
      .map(this.extractData)
      .catch(this.handleError);
  }

因此,如果当前响应和最后一个响应共享相同的特定值,则会删除最新响应。我想我的问题不够明确,我没有提到放弃回应的决定取决于前一个。

这种方法的缺点是响应必须被解析两次,但我想这是无法避免的。很高兴知道json approch是否比结果(正文)的完整字符串比较更快。

如果放弃回复的决定仅取决于当前回复,我建议使用filter