RxJS Observable.if执行两个语句

时间:2017-11-07 09:44:35

标签: javascript rxjs observable

因此,我对RxJs和Observable模式相对较新,目前我正在努力理解所提供的一些功能以及它们的行为方式。

以下是代码段:

Observable.if( //can also be onErrorResumeNext
  () => true,
  Observable.fromPromise(
    fetch('/'+ locale + '_state.json', {
      headers: {
        'Accept': 'application/json'
      },
      method: 'GET'
    }).then(res => {
      if (!res.ok) {
        throw new Error(res.statusText);
      }

      return res.json();
    })
  ),
  Observable.fromPromise(
    fetch('/'+ defaultLocale + '_state.json', {
      headers: {
        'Accept': 'application/json'
      },
      method: 'GET'
    }).then(res => {
      if (!res.ok) {
        throw new Error(res.statusText);
      }

      return res.json();
    })
  )
)

为什么这两个语句都会被执行?我是在做某事/以错误的方式接近这个还是这种预期的行为?像Observable.if的例子那样返回更简单的东西可以正常工作,但据我所知,RxJs主要用于异步数据,所以上面的例子不应该表现相同吗?

我知道我可以使用Observable.mergeMap重写Observable.if和Observable.onErrorResumeNext的行为,这就是我最终做的事情,但感觉我在这里错过了一些东西。

2 个答案:

答案 0 :(得分:1)

您正在调用fetch()两次并将结果传递给Observable.if()。 RxJs无法控制调用哪一个,因为在Observable.if()甚至运行之前你已经调用了

Observable.if()的第二个和第三个参数包含大量重复代码。为什么不这样重写:

Observable.if(() => true, locale, defaultLocale)
.mergeMap(val => 
    fetch('/'+ val + '_state.json', {
        headers: {
            'Accept': 'application/json'
        },
        method: 'GET'
    }).then(res => {
        if (!res.ok) {
            throw new Error(res.statusText);
        }
             return res.json();
    })
);

答案 1 :(得分:1)

问题是promise不是懒惰并立即执行。使计算变得懒惰的最简单方法是使用.defer,如下所示:

Observable.if( //can also be onErrorResumeNext
  () => true,
  Observable.defer(() =>
    fetch('/'+ locale + '_state.json', {
      headers: {
        'Accept': 'application/json'
      },
      method: 'GET'
    }).then(res => {
      if (!res.ok) {
        throw new Error(res.statusText);
      }

      return res.json();
    })
  ),
  Observable.defer(() =>
    fetch('/'+ defaultLocale + '_state.json', {
      headers: {
        'Accept': 'application/json'
      },
      method: 'GET'
    }).then(res => {
      if (!res.ok) {
        throw new Error(res.statusText);
      }

      return res.json();
    })
  )
)

.defer会自动将承诺升级为observable