2017-07-25 24 views
0

在下面的代码,我有一个很难理解的链式调用的顺序是: 调用的可观察代码的顺序是什么?

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. 通话记录()返回可观察
  2. 将getChange()和takeWhile合并为一个可观察对象
  3. 将getChange和TakeWhile的合并结果与间隔Observable连接起来。
  4. 呼叫getChange每5秒钟,直到状态!== '待定'

是我的上述评估是否正确?你怎么知道什么时候使用合并或concat?

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

基于@马克面包车Straten的回答,一些额外的问题:

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

  2. 如果我不关心顺序,那么使用mergeMap?

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

+0

concatMap确实是保序。该代码假定您希望在开始轮询注册表中的更改之前完成“registerDomain()”。如果不是这种情况,可以将它合并到一起,但'getChange'依赖于'registerDomain()'返回的'registerId'。 getChange的mergeMap()是因为'adminService.getChange()'很可能会返回'Observable '或'Promise ',您需要将其平铺到主流中。 –

回答

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返回一个可观察

  2. 当它发出一个值后,我们concatMap seco nd可观察从getRegisterStatus返回

  3. getRegisterStatus当检索到的信息变为'INSYNC'时,完成每个非INSYNC发射。

我不认为是真正需要的concatMap,可与mergeMap被替换,因为registerDomain很可能只发出一个值

+0

嗨,感谢迄今为止的答案,我在我的文章中提出了一些其他问题。现在我获得了更好的concatMap,但仍然很难理解mergeMap,特别是对于这种情况? – xaisoft

相关问题