RxJS:将承诺结果和承诺错误映射到不同的值

时间:2017-11-19 19:32:05

标签: javascript rxjs

以下代码有效地将承诺解决方案映射到true,并将承诺错误映射到false

onlineUpdate$
.switchMap(online => {
  switch (online) {
    default:
    case true: {
      const connected$ = new Rx.Subject();
      axios.get("/some/url/to/test/connection")
        .then(response => connected$.next(true))
        .catch(error => connected$.next(false));
      return connected$;
    }
    case false: {
      return Rx.Observable.of(false);
    }
  }
});

但是关于创建中级Rx.Subject的一些事情感觉就像我做的工作超出了我的需要。有没有更优雅或内置的方法将promise promise解析为一个值,并在不使用中间Rx.Subject或其他可观察的情况下将错误传递给另一个值?

4 个答案:

答案 0 :(得分:3)

通过Observable#fromPromise函数将Promise包装到Observable中并将promise传递给。如果承诺得到解决,Observable将发出true,如果被拒绝,则false

...
case true: {
      return Rx.Observable.fromPromise(axios.get("/some/url/to/test/connection")
                                            .then(response => true)
                                            .catch(error => false));
    }
...

简单示例。

Rx.Observable.of(false)相当于case falsePromise.resolve(true)到承诺的then函数,Promise.reject('Error').catch(err => false)承诺的catch函数。

Rx.Observable.of(false).subscribe(console.log);
Rx.Observable.fromPromise(Promise.resolve(true)).subscribe(console.log);
Rx.Observable.fromPromise(Promise.reject('Error').catch(err => false)).subscribe(console.log);
<script src="https://unpkg.com/@reactivex/rxjs@5.5.2/dist/global/Rx.js"></script>

答案 1 :(得分:1)

是的,你可以在Observable.of(false)的catch块中返回Observable.fromPromise()。同样,如果连接成功,请使用.map()返回Observable.of(true)

onlineUpdate$
    .switchMap(online => {
        switch (online) {
            default:
            case true: {
                Rx.Observable.fromPromise(axios.get("/some/url/to/test/connection"))
                    .map(() => true) // if the promise resolves to something, return an Observable.of(true)
                    .catch(() => Rx.Observable.of(false)) // else if there is any error return Observable.of(false)
            }
            case false: {
                return Rx.Observable.of(false);
            }
        }
    });

请注意,如果.map()成功解析,您必须明确Observable.fromPromise promise为真。

您可以用更简洁的方式编写代码:

onlineUpdate$
    .switchMap(online => {
        return online ?
            Rx.Observable.fromPromise(axios.get("/some/url/to/test/connection"))
                .map(() => true)
                .catch(() => Observable.of(false))
            : Observabe.of(false)
    });

答案 2 :(得分:1)

switchMap运算符适用于所谓的Observable input,这意味着您只需返回Promise而不将其转换为Observable:

onlineUpdate$
.switchMap(online => {
  switch (online) {
    default:
    case true: {
      return axios.get("/some/url/to/test/connection");
    }
    case false: {
      return Rx.Observable.of(false);
    }
  }
})
.catch(() => Rx.Observable.of(false))
.map(Boolean) // force convert to boolean

请注意,这与你写的不一样。 catch运算符会捕获所有错误,即使它们不是来自前面的axios.get调用,但在您的情况下可能无关紧要。

答案 3 :(得分:0)

事实证明,根本不需要使用Observable.fromPromise()。使这项工作最直接的变化是:

onlineUpdate$
.switchMap(online => {
  switch (online) {
    default:
    case true: {
      return axios.get("/some/url/to/test/connection")
        .then(response => true)
        .catch(error => false);
    }
    case false: {
      return Rx.Observable.of(false);
    }
  }
});

或者,如果您更喜欢三元组而不是switch语句:

onlineUpdate$
.switchMap(online => {
  return online ?
    axios.get("/some/url/to/test/connection")
      .then(response => true)
      .catch(error => false)
    : Rx.Observable.of(false);
});