可观察的代码以什么顺序调用?

时间:2017-07-25 14:12:47

标签: rxjs

在下面的代码中,我很难理解链接调用的顺序是:

 function registerDomain(caseWebsiteUrl) {
    return this._adminService.registerDomain(caseWebsiteUrl.Url)
      .concatMap(registerId => Observable.interval(5000)
        .mergeMap(() => this._adminService.getChange(registerId))
        .takeWhile((info) => info.ChangeInfo.Status.Value !== 'INSYNC')
      )
  }
  registerDomain.subscribe(res => console.log('res:'+res));

我想了解上面的代码,但我很难理解订单。当我看到一个更简单的例子时,我更容易理解:

function registerDomain() {
    return register()
      .concatMap(registerId => Rx.Observable.interval(5000)
        .mergeMap(() => 
          getChange(registerId))
        .takeWhile((info) => info === 'PENDING')
      );
  }

  registerDomain().subscribe(x=>console.log(x));



  function register()
  {
  return Rx.Observable.of("registerId");
  }


  function getChange(registerId)
  {
   //at some point this will return INSYNC
    return Rx.Observable.of("PENDING");
  }

当我查看这段代码时,我的阅读方式是:

  1. 调用register()返回一个observable
  2. 将getChange()和takeWhile合并为一个可观察的
  3. 将getChange和TakeWhile的合并结果与Observable区间连接起来。
    1. 每隔5秒调用一次getChange,直到状态!=='PENDING'
  4. 我的上述评估是否正确?你怎么知道何时使用merge或concat?

    如果我想捕获错误,例如,register()会抛出错误,那么它应该失败。

    基于@Mark van Straten的回答,还有一些问题:

    1. 所以如果我想保留顺序,我应该使用concatMap?在这种情况下,我希望在调用getChange之前完成registerDomain?

    2. 如果我不关心订单,那么使用mergeMap?

    3. 在getRegisterStatus方法中,它到底在哪里合并?为什么不使用concatMap?

1 个答案:

答案 0 :(得分:1)

有三个运算符用于展平高阶可观测值:

  • mergeMap(又名flatMap) - 合并所有流,排放交错
  • concatMap - 在第一个流完成 concat 之后的下一个等
  • switchMap - 放弃第一个流,切换到达下一个流 所以给出了代码:
function registerDomain(caseWebsiteUrl) {
    return this._adminService.registerDomain(caseWebsiteUrl.Url)
      .concatMap(registerId => Observable.interval(5000)
        .mergeMap(() => this._adminService.getChange(registerId))
        .takeWhile((info) => info.ChangeInfo.Status.Value !== 'INSYNC')
      )
  }
  registerDomain.subscribe(res => console.log('res:'+res));

我们可以按如下方式重写:

function registerDomain(caseWebsiteUrl) {
  return this._adminService.registerDomain(caseWebsiteUrl.Url)
    .concatMap(registerId => getRegisterStatus(registerId))
}

function getRegisterStatus(registerId) {
  return Observable.interval(5000)
    .mergeMap(() => this._adminService.getChange(registerId))
    .takeWhile((info) => info.ChangeInfo.Status.Value !== 'INSYNC')
}
  1. 首先_adminService .registerDomain返回一个Observable

  2. 在发出值concatMap之后,从getRegisterStatus

  3. 返回的第二个观察值 当检索到的信息变为“INSYNC”时,
  4. getRegisterStatus完成,将发出每个非INSYNC发射。
  5. 我不认为concatMap真的需要并且可以用mergeMap替换,因为registerDomain很可能只发出一个值

相关问题