2016-09-23 70 views
2

我一直在使用一個約定,其中我的函數返回observables以實現一系列強制順序函數調用,每個函數都將返回值傳遞給它們的下一個「回調」函數。但在閱讀和觀看教程後,我認爲我可以用我認爲是flatmap的更好的方式做到這一點。我認爲我接近這個建議https://stackoverflow.com/a/34701912/2621091雖然我沒有開始承諾。下面列出了我希望通過更好的方法幫助清理建議的例子。我非常感謝幫助你可以提供:將回調地獄轉換爲可觀察鏈

grandparentFunction().subscribe(grandparentreturnobj => { 

    ... oprate upon grandparentreturnobj ... 

}); 


grandparentFunction() { 

    let _self = this; 

    return Observable.create((observer) => { 

     ... 

     _self.parentFunction().subscribe(parentreturnobj => { 

      ... 

      _self.childFunction(parentreturnobj).subscribe(childreturnobj => { 

       ... 

       observer.next(grandparentreturnobj); 
       observer.complete(); 
      }); 
     }); 
    }); 
} 


parentFunction() { 

    let _self = this; 

    return Observable.create((observer) => { 

     ... 

     observer.next(parentreturnobj); 
     observer.complete(); 
    } 
} 


childFunction() { 

    let _self = this; 

    return Observable.create((observer) => { 

     ... 

     observer.next(childreturnobj); 
     observer.complete(); 
    } 
} 

回答

1

在RxJS的一般規則的拇指是,你應該儘量避免創建手工製作,定製的觀測量(即使用Observable.create()),除非你知道你在做什麼,並且無法避免它。有一些棘手的語義,如果你沒有牢牢掌握RxJS的'合同',很容易引起微妙的問題,因此通常嘗試使用現有的Observable創建函數會更好。更好的是,通過在現有的Observable上應用運算符來創建Observables,然後返回它。

根據對示例代碼的具體批評,您應該使用.flatMap()來創建Observable函數鏈。你現在擁有的嵌套Observable.create()不是很像Rx的,並且遭受同樣問題的回調地獄式代碼。

下面是一個做你的例子做同樣的事情,但在一個更習慣性的Rx風格的例子。 doStuff()是我們想要創建的異步功能。 doStuff()需要調用異步函數step1(),將其結果鏈接到異步函數step2()中,然後對結果進行一些進一步操作,並將最終結果返回給doStuff()的調用者。

function doStuff(thingToMake) { 
    return step1(thingToMake) 
     .flatMap((step1Result) => step2(step1Result)) 
     .map((step2Result) => { 
      let doStuffResult = `${step2Result}, and then we're done`; 
      // ... 
      return doStuffResult; 
     }); 
} 

function step1(thingToMake) { 
    let result = `To make a ${thingToMake}, first we do step 1`; 
    // ... 
    return Rx.Observable.of(result); 
} 

function step2(prevSteps) { 
    let result = `${prevSteps}, then we do step 2` 
    // ... 
    return Rx.Observable.of(result); 
} 

doStuff('chain').subscribe(
    (doStuffResult) => console.log(`Here's how you make a chain: ${doStuffResult}`), 
    (err) => console.error(`Oh no, doStuff failed!`, err), 
    () => console.debug(`doStuff is done making stuff`) 
) 

Rx.Observable.of(x)是現有的可觀察創建者函數的一個例子。它只是創建一個返回x的Observable,然後完成。