Angular 4.3 可观察量 : how to retry with an interval and max retries?

标签 angular observable

我是 Angular 4.3 的新手。我有一个 map 应用程序,它通过下载一系列小图像(“图 block ”)来呈现“ map 层”。在启动时, map 层可能需要 0.1 - 5.0 秒的时间来下载。

我需要在客户端收到两个或多个图 block 时触发一个事件。我原以为我可以通过订阅一个以 200 毫秒为间隔重试最多 30 次的 Observable 来实现这一目标。

到目前为止:

  public updateTileContainer() {
    this._getTileContainer().subscribe(container => {
      if (container) {
        console.log('* do stuff with container *');
      }
    });
  }

  private _getTileContainer(): Observable<any> {

    return Observable.interval(200)
      .mergeMap(function (n) {

        const tileImages = $('#mymap').find('img[src*=\'kml\']');

        console.log(`Retry ${n}: ${tileImages.length} tiles found`);

        if (!tileImages || tileImages.length < 2) {
          return Observable.of(null);
        }

        const tileContainer = getContainer(tileImages);

        return Observable.of(tileContainer);
      })
      .take(30);
  }

这行得通!有点。我得到这个输出:

Retry 0: 0 tiles found
Retry 1: 0 tiles found
Retry 2: 0 tiles found
Retry 3: 0 tiles found
Retry 4: 0 tiles found
Retry 5: 0 tiles found
Retry 6: 0 tiles found
Retry 7: 2 tiles found
* do stuff with container *
Retry 8: 3 tiles found
* do stuff with container *
Retry 9: 9 tiles found
* do stuff with container *
Retry 10: 12 tiles found
* do stuff with container *
etc.

我实际上想做的是在“重试 7”时发出一个事件,然后停止发出。

我如何才能将其更改为在找到容器后立即“完成”Observable?我如何“跳过”重试 0 到 6 的发射事件,因为它们不是真正的事件?如果重试 30 次仍未找到容器,我是否可以从 Observable 中抛出错误?

最佳答案

使用.retry(count)

如果您的选择中的图 block 少于 2 个,您可能会抛出错误。然后 retry() 30 次。

注意:第 30 次重试后,错误实际上会发出,您需要处理它。但这可能是一件好事(进一步了解)。

public updateTileContainer() {
  this._getTileContainer().subscribe(container => {
      console.log('* do stuff with container *');
  },error=>{
      console.log('no container found !');
  });
}

private _getTileContainer(): Observable <any> {
  return Observable.timer(200).map(()=>{
    const tileImages = $('#googlemap').find('img[src*=\'kml\']');
    if (tileImages.length <= 2)
      throw new Error("not enough tiles !");
    return getContainer(tileImages);
  })
  .retry(30);
}

您的解决方案和@JonStødle 的确实有效。但请注意,如果您无法获得任何容器,您将不会收到通知。事实上,如果没有找到容器,Observable 就完成了,没有错误。

如果您想知道您无法找到容器,处理错误可能是一件好事。

关于 Angular 4.3 可观察量 : how to retry with an interval and max retries?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46754545/

相关文章:

javascript - 将新对象绑定(bind)到 Angular 表单而不是单个属性

JavaFX 客户端 UI 不会显示主机触发的警报

angular - 可从字符串中观察到(Angular 2)

angular - Angular 4 如何将数据从父组件传递到子组件

javascript - Angular2 导入自定义 JavaScript 库

java - 如何清理 Rx Subscription 和 Observable 以防止内存泄漏?

javascript - (dojo)Observable无法观察到Memory Store的变化

angular - 使用 RxJS 可观察对象在可观察对象返回后采取行动时, 'do' 和 'finally' 之间有什么区别?

Angular Material Mat-Select ngModel bool 值不起作用

javascript - 为什么 $event 绑定(bind)在使用 PrimeNG 的 RowGroup 表上不起作用?