2016-07-22 48 views
0

上下文:應用程序在打字稿與Angular2寫,+ rxjs 5.RxJs:在可觀察<T>數組「地圖」,但只要返回作爲一件T匹配的條件

編輯:我precising我對於Rx圖書館來說是相對較新的事物,應該以「慣用的方式」來完成。是的,我試圖在發佈SO之前在文檔中找到一些線索。

我有這樣的:

class Result { constructor(public inError: boolean) { } } 

const checks : Array<() => Observable<Result>> = [...]; 

這是函數數組,每個函數返回一個可觀察到的這種意願包含一個結果對象。

我想要什麼:

  • 我想通過依次調用每個函數此陣「地圖」爲Array<Observable<Result>>, 基本上...
  • ...但我想打破'地圖「,只要第一個Result.inError是真的!

我desesperalty卡住,與reducetakeWithcontains等.. 可觀測量的遞延性質的我百思不得其解擺弄。

任何幫助將不勝感激!

+0

也許在downvoter可以解釋他爲什麼downvoted我的問題? –

回答

0

如果你的觀測量進行同步操作,您可以簡單地這樣做:

const results = []; 
for (const i = 0; i < checks.length; i +=1) { 
    checks[i]().subscribe(result => if (result.inError) { 
     break; 
    } else { 
     results.push(checks[i]()); 
    }); 
} 
// Results observables accessible here. 

在異步觀察家情況:

const results = []; 
function callObservable(index) { 
    checks[index]().subscribe(result => if (result.inError) { 
      // Results observables accessible here. 
     } else { 
      results.push(checks[i]()); 
      callObservable(index + 1); 
     }) 
} 
callObservable(0); 

做任何的,不給任何好處,雖然。你的observables已經被調用,甚至在它們到達結果數組之前,或者如果再次從這個數組中調用,將會有另一個值。

0

越來越多的挖掘後,這裏是一個解決方案:

// Some class that will be contained in my observables 
class Result { constructor(public inError: boolean) { } } 

// An array of Observables that will emit those classes instances 
// the thunk is just here to lazy instantiate the Result classes 
// only when needed 
const oResults : Array<() => Observable<Result>> = [ 
    Rx.Observable.of(() => new Result(false)), 
    Rx.Observable.of(() => new Result(false)), 
    Rx.Observable.of(() => new Result(true)), 
    Rx.Observable.of(() => new Result(false)) 
]; 

// An home made (found on SO) INCLUSIVE 'takeWhile' version 
const takeWhileInclusive(source, predicate){ 
    return source.publish(co => co.takeWhile(predicate) 
     .merge(co.skipWhile(predicate).take(1))); 
} 

// Let's filter out things as expected 
const res = takeWhileInclusive(
    Rx.Observable.merge(oResults).map(x => x()), 
    x => !x.inError 
); 

// I can now subscribe to the resulting stream and will only get 
// all the first Results that are false AND the first following result that 
// is true 
res.subscribe(next => console.info("Next result", next));