[英]Combine observable responses into one
如何從多個可觀察對象中獲取對象響應?
我的史詩喜歡這樣:
export function metaDataEpic(action$: ActionsObservable<metaDataActions>) {
return action$.ofType(META_DATA_REQUEST)
.mergeMap((action: metaDataActions) => {
const { language } = action;
return Observable.merge(
Observable.fromPromise(couriersApi().then(r => r.json())),
Observable.fromPromise(itemCategoriesApi({ language }).then(r => r.json())),
Observable.fromPromise(airportsApi().then(r => r.json())))
.flatMap(res => {
console.log(res);
return Observable.of(getMetaDataSuccess({}))
});
});
}
我需要的是通過我的功能getMetaDataSuccess()
從響應對象courierApi()
itemCategoriesApi()
和airportsApi()
這樣的getMetaDataSuccess({ couriers, items, airports })
但首先我需要等待所有的三個承諾完成並以某種方式在對象中組合作為響應。
我的代碼現在所做的是打印來自API的響應,從而調用getMetaDataSuccess
3次。 enter code here
聽起來你想要這樣的東西。
export function metaDataEpic(action$: ActionsObservable<metaDataActions>) {
return action$.ofType(META_DATA_REQUEST)
.flatMap(({language}) => Promise.all([
couriersApi(),
itemCategoriesApi({language}),
airportsApi()
].map(p => p.then(r => r.json()))
)
.then(([couriers, items, airports]) => ({couriers, items, airports}))
)
.do(console.log)
.map(getMetaDataSuccess);
}
flatMap
aka mergeMap
可以直接在Promise和Arraylike值上運行。 這里我們使用Promise.all
來等待多個Promises的結果。 Promise.all
返回一個Promise,它解析為一個數組,其中每個元素都是輸入數組中相應項的結果。 我們將這個數組轉換為一個對象並傳遞它。
在這里,虛擬數據證明它有效。
function couriersApi() { return Promise.resolve({ json: () => [{ name: 'x', id: 1 }, { name: 'y', id: 2 }] }); } function airportsApi() { return Promise.resolve({ json: () => [{ name: 'ORF', id: 1 }, { name: 'JFK', id: 2 }] }); } function itemCategoriesApi({language}) { return Promise.resolve({ json: () => [{ name: 'a', language: 'German' }, { name: 'b', language: 'English' }, ].filter(c => c.language === language) }); } const META_DATA_REQUEST = undefined; const action$ = { ofType: () => Rx.Observable.of({ language: 'English' }) }; metaDataEpic(action$) .subscribe(); function getMetaDataSuccess(o) { console.log(o.couriers); console.log(o.items); console.log(o.airports); } function metaDataEpic(action$) { return action$.ofType(META_DATA_REQUEST) .flatMap(({ language }) => Promise.all([ couriersApi(), itemCategoriesApi({ language }), airportsApi() ].map(p => p.then(r => r.json()))) .then(([couriers, items, airports]) => ({ couriers, items, airports })) ) .do(console.log) .map(getMetaDataSuccess); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"></script>
我有兩個解決方案,你可以嘗試一下,如果他們在你的情況下工作:
export function metaDataEpic(action$: ActionsObservable<metaDataActions>) {
return action$
.ofType(META_DATA_REQUEST)
.mergeMap((action: metaDataActions) => {
const {language} = action;
const requestObservable = Observable.zip(
Observable.fromPromise(couriersApi().then(r => r.json())),
Observable.fromPromise(
itemCategoriesApi({language}).then(r => r.json())
),
Observable.fromPromise(airportsApi().then(r => r.json())),
(couriers, items, airports) => {
return Observable.of(getMetaDataSuccess({ couriers, items, airports })) ).map(response => response.value)
}
).catch(e => {
return Observable.of(getMetaDataFail(e));
});
return requestObservable;
});
}
要么
export function metaDataEpic(action$: ActionsObservable<metaDataActions>) {
return action$
.ofType(META_DATA_REQUEST)
.mergeMap((action: metaDataActions) => {
const {language} = action;
Promise.all(
[couriersApi(), itemCategoriesApi({language}), airportsApi()].map(p =>
p.then(r => r.json())
)
)
.then(([couriers, items, airports]) => {
return Observable.of(getMetaDataSuccess({couriers, items, airports}));
})
.catch(e => {
return Observable.of(getMetaDataFail(e));
});
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.