使用RxJS和React,我遇到了如何在另一个Observable的map中生成的Observable.fromPromise中等待数据的问题。
我有异步助手:
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)))
);
然后我actions.fetchClients$
Rx.Subject
:
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
,它运行正常(使用ava
)并提供数据:
test('dataStreamGenerator', t => {
const ds$ = dataStreamGenerator(CLIENTS_DATA_URL);
return ds$.do((data) => {
t.is(data.length, 10);
});
});
(AVA自动订阅observable并使用它,因此无需订阅)。
但是actions.fetchClients$.map((url = CLI...
第二张地图(开始...... console.log('GOT DATA IN REDUCER: ', val);...
仍在获取Observable而不是dataStream $中的数据。
我在fetchClients $ code中尝试了map
和flatMap
的所有可能组合,但仍然没有运气。
我的测试代码是:
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');
});
我无法弄清楚如何等待Observable dataStreamGenerator(url);
发出数据而不是Observable。
感谢。
答案 0 :(得分:2)
您需要压缩从'x.c'::gvar
返回的结果。
dataStreamGenerator
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
将展平flatMap
,Observables
和{{1}这样他们的价值就会被传播。
它适用于测试用例,因为您直接订阅Arrays
返回的Promises
。