2016-07-11 15 views
1

RxJSとReactで再生すると、Observable.fromPromiseのデータが別のObservableのマップ内で生成されるのを待つ方法の問題があります。解決するためにObservable.flatMapを作成する方法

私は非同期ヘルパーを持っている:

const dataStreamGenerator = (url = CLIENTS_DATA_URL) => (
    Rx.Observable.fromPromise(fetch(url)) 
    .flatMap(response => Rx.Observable.fromPromise(response.json())) 
    .catch(err => Rx.Observable.of(new Error(err))) 
); 

その後、私はRx.Subjectあるactions.fetchClients$を持っている:

actions.fetchClients$.map((url = CLIENTS_DATA_URL) => { 
    const ts = Date.now(); 
    console.log('FETCH CLIENTS with: ', url); 
    return dataStreamGenerator(url); 
    }).map(val => { 
    console.log('GOT DATA IN REDUCER: ', val); 
    const error = (val instanceof Error) ? val.message : undefined; 
    const data = error ? undefined : val; 
    actions.receivedClientsData$.next({ data, error, ts: Date.now() }); 
    return (state) => state; 
    }) 

(はい、RxJSでReduxのを模倣しようとしています)。

私はdataStreamGeneratorをテストWhan、それは(avaで)OK動作し、データを提供します。

test('dataStreamGenerator', t => { 
    const ds$ = dataStreamGenerator(CLIENTS_DATA_URL); 
    return ds$.do((data) => { 
    t.is(data.length, 10); 
    }); 
}); 

(AVAが自動的に観測可能に加入し、それを消費するので、サブスクライブする必要はありません)。

しかしactions.fetchClients$.map((url = CLI...第2のマップ(開始... console.log('GOT DATA IN REDUCER: ', val);...はまだデータストリーム$。

から観察可能とされていないデータを取得しているが、私はfetchClients $コードでmapflatMapのすべての可能な組み合わせが、まだ運を試してみました。

私のテストコードは次のとおりです。

test.only('fetchClients$', t => { 
    const initialState = {}; 
    actions.fetchClients$.next('http://jsonplaceholder.typicode.com/users'); 
    reducer$.subscribe(val => { 
    console.log('TEST SUBSCRIBE VAL: ', val); 
    t.pass(); 
    }); 
    actions.fetchClients$.next('http://jsonplaceholder.typicode.com/users'); 
}); 

私は、データaを発するように観察可能dataStreamGenerator(url);に待つ方法を見つけ出すカントObservableはありません。

ありがとうございました。

答えて

2

dataStreamGeneratorから返された結果をフラット化する必要があります。ストリームダウンそのままflatMapObservablesArraysPromisesその値が伝播し得るものであるように平らになるのに対し、

actions.fetchClients$ 
    //This is now a flatMap 
    .flatMap((url = CLIENTS_DATA_URL) => { 
    const ts = Date.now(); 
    console.log('FETCH CLIENTS with: ', url); 
    return dataStreamGenerator(url); 
    }); 

map演算子は、値を提供します。

Observableに直接サブスクライブしているので、テストケースではdataStreamGeneratorが返されます。

+0

ありがとう@paulpdaniels。私はこれまでにも試しましたが、テスト結果に困惑しました。全体的な問題はavaであると思われます。フェッチが解決され、早期に完了するのを待つことなく(最初の値が渡された後)。タグに 'ava'を追加する必要があります。 – DavidC

関連する問題