Rx fromPromise 并重试

Rx fromPromise and retry

为什么你必须 flatMap fromPromise 才能让 retry 工作?
('/error' returns 状态 500)

var responseStream = Rx.Observable.just('/error').
        flatMap(requestUrl => {
            return Rx.Observable.fromPromise(_this.$http.get(requestUrl));
    });

    responseStream.
        retry(3).
        subscribe(
        function (x) {
            console.log('Next: ' + x);
        },
        function (err) {
            console.log('Error: ' + err);
        },
        function () {
            console.log('Completed');
        });

我想打断仪式,只说:

Rx.Observable.fromPromise(_this.$http.get('error')).
        retry(3).
        subscribe(
        function (x) {
            console.log('Next: ' + x);
        },
        function (err) {
            console.log('Error: ' + err);
        },
        function () {
            console.log('Completed');
        }); 

在第二种情况下,xhr 调用只执行一次。

因为 Promises 没有 API 重试。 fromPromise 只是包装 Promise 并让它通过 Observable 发出。当您调用 _this.$http.get('error') 时,您已经创建了一个 Promise 并且它已经在运行中,因此如果不再次调用该方法就无法重试承诺。

它在用 flatMap 包装时起作用的原因是,当您重试 Observable 时,它实际上是在重新执行生成承诺的方法。

如果冗长确实对您造成伤害,请注意许多运算符隐式支持 Promises,无需调用 fromPromise 方法。

因此您的示例可以简化为

var responseStream = Rx.Observable.just('/error')
        .flatMap(requestUrl => _this.$http.get(requestUrl));

    responseStream
        .retry(3)
        .subscribe(
          (x) => console.log('Next: ' + x),
          (err) => console.log('Error: ' + err),
          () => console.log('Completed'));

或者更简单地使用 defer:

Observable.defer(() => _this.$http.get('/error'))
   .retry(3)
   .subscribe(
      (x) => console.log('Next: ' + x),
      (err) => console.log('Error: ' + err),
      () => console.log('Completed'));