簡體   English   中英

將可觀察的反應合並為一個

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM