Redux-Observable отправляет несколько действий и ждет ответов - PullRequest
0 голосов
/ 25 февраля 2020

Я пытаюсь отправить несколько действий, а затем выполнить второй шаг после выполнения всех начальных действий. Я могу отправить несколько действий, но не могу дождаться их ответа. Вместо массива ответных действий я получаю массив с запросом действий. С Redux-Observables, как я могу отправить несколько действий, подождать, пока все они завершатся, а затем выполнить дополнительный шаг с их ответами? Я пробовал разные операторы, такие как forkJoin, concat, но в итоге я столкнулся с той же проблемой.

interface Action1ResponseType { 
  id: string;
  name: string;
  address: Address;
  ...
}

interface Action2ResponseType { 
  id: string;
  addressId: string;
  addressValidation: AddressValidation;
  ...
}

interface Action3ResponseType { 
  id: string;
  addressId: string;
  addressHistory: AddressHistory
  ...
}

interface PageLoaded {
  viewModels: [{
    addressToInspect: { 
      id: string;
      address: Address;
      history: AddressHistory;
      validation: AddressValidation;
      ...
    }]
  }
  ...
}
import { createAction } from 'typesafe-actions';

const action1 = () => createAction('ACTION1')<Action1ResponseType[]>();
const action2 = () => createAction('ACTION2')<Action2ResponseType[]>();
const action3 = () => createAction('ACTION3')<Action3ResponseType[]>();

// Usage example:
const action1ToDispatch = action1({id: '123'});
// action1ToDispatch (the request) will be:
// {
//   type: 'ACTION1',
//   payload: {
//     id: '123'
//   }
// }
dispatch(action1ToDispatch);
Example responses:
action1:
const response1: Action1ResponseType[] = [
  {
    id: '456',
    name: 'helloworld',
    address: {
      id: '789'
      ...
    } 
  }
];

const response2: Action2ResponseType[] = [
  {
    id: '543',
    addressId: '789',
    addressValidation: {...}
  }
];

const response3: Action3ResponseType[] = [
  {
    id: '321',
    addressId: '789',
    addressHistory: {...}
  }
];
export const myEpic = (action$) => {
  return action$.pipe(
    ofType('myActionType'),
    switchMap((action) => {
      const x = ...; // Perform some initial work before API calls

      return forkJoin([
        action1(x),
        action2(x),
        action3(x),
      ]);
    }),
    // The following function is not correct.  Instead of receiving an array of responses, an array of request actions are passed.
    map(results => {
      const [response1, response2, response3] = results;
      const pageLoadData = ...; // Iterate the various address that are returned and attempt to merge data from response1, response2, and response2.

      return {
        type: 'PageLoaded',
        data: pageLoadData,
      };
    })
  );
};

1 Ответ

0 голосов
/ 28 февраля 2020
return forkJoin([
        action1(x),
        action2(x),
        action3(x),
      ]);

У вас есть правильная идея вернуть массив запросов действий в switchMap. Если action1 и др. c. не нужно быть действием Redux, они могут просто вернуть обещание (например, вызов fetch):

const action1 = (x) => fetch(url, 
    // ...
);

Тогда map(results => { будет содержать массив разрешенных ответов от action1 и др. c из switchArray.

...