Испускать 2 значения из наблюдаемого за редукцией эпоса, когда source $ - это одно действие

Я пытаюсь вернуть два отдельных значения из эпоса с учетом единого источника $ action. Однако - кажется, я могу сделать это, только явно подписавшись на внутренний Observable. Моя эпопея сейчас выглядит так:

export const orderItemEpic = action$ =>
  action$.ofType(ORDER_ITEM)
    .switchMap(action => Observable.of(
        api.createOrder(action.payload.order),
        api.updateItem(action.payload.item, action.payload.item._id)
    ))
    .map(val => console.log('Outer Observable', val));

Однако это только испускает обещание первого запроса api (хотя оба вызываются)

Единственный способ получить два значения одновременно - это явно подписаться на внутренний Observable. Вот так:

export const orderItemEpic = action$ =>
  action$.ofType(ORDER_ITEM)
    .switchMap(action => Observable.of(
        api.createOrder(action.payload.order),
        api.updateItem(action.payload.item, action.payload.item._id)
    ).map(val => val).subscribe(v => console.log('Inner Observable', v))
    .map(val => console.log('Outer Observable', val)); //never gets called

Но теперь моя «Внешняя» наблюдаемая не отображается.

Когда я издеваюсь над этим с помощью JSBin, кажется, что первый пример должен выдавать ответ от обоих вызовов api. http://jsbin.com/cejolegixo/edit?js,console

Думаю, мне просто интересно, это какая-то причуда в redux-observable или я что-то делаю неправильно.

Спасибо


person Rody Kirwan    schedule 02.12.2017    source источник


Ответы (1)


Это потому, что у вас есть 3 уровня Observable.

это выдает только обещание первого запроса API

Ваш JSBin более точно отражает код, если вы используете

// First Mock API
const firstAPI = res => Rx.Observable.of({...res})

// Second Mock API
const secondAPI = res => Rx.Observable.of({...res})

Итак, исправление состоит в том, чтобы «объединить» внутренние наблюдаемые.

// map value from source into inner observable, when complete emit result and move to next
const stream = source$.switchMap(action => Rx.Observable.merge(
  firstAPI(action.payload.a),
  secondAPI(action.payload.b)
))

Ссылка JSBin

Кстати, вы можете flatMap вместо switchMap. Зависит от того, какое поведение вы хотите.

switchMap отменит первый заказ, когда придет второй, в то время как первый находится в процессе (кажется плохим, если это разные заказы).

person Richard Matsen    schedule 02.12.2017
comment
Привет, Ричард, спасибо за ответ. Ваше решение по-прежнему не работает для наблюдаемого сокращения ... и да, конечно, вы правы - мои запросы API являются обещаниями, но ваш пример JSBin возвращает точно так же, как мой ... Мне интересно, не понимаю ли я, как действия подписываются под капотом в redux-observable. Опубликую проблему в репо и посмотрю, есть ли у них какие-либо идеи ... Также спасибо за совет flatMap, но switchMap - это то, что я ищу. - person Rody Kirwan; 03.12.2017
comment
На самом деле, поцарапайте это ... проблема заключалась в том, что я просто регистрировал вывод, а не запускал действие. Произошла ошибка, которая блокировала последующие функции карты. - person Rody Kirwan; 03.12.2017
comment
Вы меня сейчас потеряли, объясните, пожалуйста, поподробнее. - person Richard Matsen; 03.12.2017
comment
Да ладно ... это была моя собственная глупая ошибка: D. Исходный поток работает правильно - он просто ломался, потому что redux-observable требует действия в качестве окончательного вывода. Спасибо, в любом случае. - person Rody Kirwan; 05.12.2017