Как сделать несколько запросов HTTP с RxJS и объединить ответ в одну полезную нагрузку и сопоставить его с другим действием? - PullRequest
0 голосов
/ 14 октября 2019

В соответствии с заголовком я пытался найти способ сделать несколько HTTP-вызовов из полезной нагрузки действия и в основном объединить все результаты в один массив, а затем отобразить результат в другое действие в качестве полезной нагрузки.

Вот мой существующий код, он работает, но кажется, что он не объединяет оба ответа и заботится только о последнем ответе от ответа на запрос, возможно, я использую неправильный оператор, я просто беру RxJS и пытаюсьразные вещи для изучения, надеюсь, кто-нибудь сможет объяснить, где я ошибаюсь.

Любая помощь или направление высоко ценится.


{
    type: 'FETCH_DATA',
    payload: {
        key: 'standings',
        value: [
                'http://url-1',
                'http://url-2'
        ],
    })
}


// The epic is listening to the above action

const fetchDataEpic = action$ => action$.pipe(
    ofType('FETCH_DATA'),
    mergeMap(action => {
        const { key, value } = action.payload;
        if (Array.isArray(value) && value.length) {
            const makeRequest = value.map((x, i) => ajax.getJSON(value[i]))

            return (
                forkJoin(
                    makeRequest,
                    response => {
                        return ({
                            type: 'FETCH_DATA_SUCCEEDED',
                            payload: {
                                key,
                                value: response,
                            },
                        })
                    }
                )
            )
        }
    })
);

ПРИМЕЧАНИЕ. Ответ на оба запроса находится в одном и том же JSONформат с теми же свойствами, но разными данными.

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 14 октября 2019

похоже, вы используете ajax-функцию rxjs, которая уже должна давать вам наблюдаемые. В этом случае forkJoin должен предоставить вам оба значения в виде массива, как только все наблюдаемые имеют выданные значения. И затем вы можете добавить к своей полезной нагрузке действия с функцией карты.

const requestArrays = [1, 2].map(i => {
  return rxjs.ajax.ajax.getJSON(`https://jsonplaceholder.typicode.com/posts/${i}`);
});

rxjs.forkJoin(requestArrays)
  .pipe(
    rxjs.operators.tap(resp => {
      console.log('Part 1: Response so far: ');
      console.log(resp);
    }),
    rxjs.operators.map(value => {
      return {
        type: 'FETCH_DATA_SUCCEEDED',
        payload: {
          value
        }
      };
    }),
    rxjs.operators.tap(resp => {
      console.log('Part 2: Result as a action payload: ');
      console.log(resp);
    }),
  )
  .subscribe();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>

РЕДАКТИРОВАТЬ: Вот как примерно вы бы это реализовали.

const action = {
  type: 'FETCH_DATA',
  payload: {
    value: [
      '1',
      '2'
    ],
  }
};

rxjs.of(action)
.pipe(
    rxjs.operators.mergeMap(action => {
      const requestArrays = action.payload.value.map(i => {
        return rxjs.ajax.ajax.getJSON(`https://jsonplaceholder.typicode.com/posts/${i}`);
      });
      return rxjs.forkJoin(requestArrays)
      .pipe(
          rxjs.operators.map(value => {
            return {type: 'FETCH_DATA_SUCCEEDED', payload: {value}};
          })
      )
    })
)
.subscribe(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>
0 голосов
/ 14 октября 2019

Я не думаю, что это касается только ответа last , но first one.

Это потому, что если вы хотите настроитьответ из forkJoin, второй (или последний, если первый не является массивом) аргумент (который является функцией) принимает несколько аргументов , которые являются ответами от предоставленногозапросов.

Таким образом, это изменение я бы выполнил, чтобы получить весь массив ответов.

/* ... */
forkJoin(
    makeRequest,
    (...response) => {
        return ({
            type: 'FETCH_DATA_SUCCEEDED',
            payload: {
                key,
                value: response,
            },
        })
    }
)
/* 

Редактировать: отправить объединенные ответы другому действию

Этого можно добиться с помощью оператора tap , который обычно используется, когда вам приходится иметь дело с побочными эффектами.

(
 mergeMap(action => { ... }),
 tap(action => sendToOtherAction(action))
)
...