Redux-Observable выполняет запрос ajax / rx js внутри цикла - PullRequest
0 голосов
/ 12 июля 2020

у меня есть оболочка rxjs/ajax, которую я могу использовать в epi c вот так

export function someEpic(action$, state$, { api }) {
  return action$
    .pipe(
      ofType(SOME_TYPE),
      map(() => ({
        ...
      })),
      map((payloads) => ({
        ...
      })),
      mergeMap((options) => api(options)
        .pipe(
          map(({ response }) => someDispatchSuccess(response)),
          catchError((response) => of(
            someDispatchFailure(response),
          )),
        )),
      catchError((response) => of(
        someDispatchFailure(response),
      )),
    )
}

Это хорошо работает для выполнения одного запроса, но у меня есть вариант использования, когда я вызываю getCategories API и сохраните ответ на состояние в (скажем) от state$.value.Some.categories до someCategoriesSuccess(response)

Теперь, используя эти доступные категории, я хотел бы повторить state$.value.Some.categories и выполнить (скажем, ) getProductsByCategoryId вызов api

// state$.value.Some.categories 
[{
  id: 'category#1_id'
  name: 'category#1_name'
}]

Как я могу сделать что-то вроде

export function someEpic(action$, state$, { api }) {
  return action$
    .pipe(
      ofType(SOME_TYPE),
      mergeMap((options) => {
        const { categories } = state$.value.Some
        return categories.map(() => api(options)
          .pipe(
            map(({ response }) => someDispatchSuccess(response)),
            catchError((response) => of(someDispatchFailure(response))),
          ))
      }),
      catchError((response) => of(
        someDispatchFailure(response),
      )),
    )
}

, что предыдущий код вызовет ошибку Actions must be in plain object, я также попытался выполнить итерацию снаружи, например,

// someEpic.js
export function someEpic(action$, state$, { api }) {
  return action$
    .pipe(
      ofType(SOME_TYPE),
      map(() => ({
        ...
      })),
      map((payloads) => ({
        ... // cat.id is being parsed as params here
      })),
      mergeMap((options) => api(options)
        .pipe(
          map(({ response }) => someDispatchSuccess(response)),
          catchError((response) => of(
            someDispatchFailure(response),
          )),
        )),
      catchError((response) => of(
        someDispatchFailure(response),
      )),
    )
}

// someContainer.js
const { categories } = state.Some

const promises = categories
  .map(async (cat) => {
    const cats = await homeCombinedEpic(
      of(homeCategories(cat.id)),
      state$,
    ).toPromise()

    return store.dispatch(cats)
  })

ПРИМЕЧАНИЕ: я использую next. js и вызываю приведенный выше пример внутри метода static async getInitialProps(), в соответствии с этим примером

console.log() Я поставил здесь и там говорится, что он действительно отправляет и выполняет вызов api правильно (несколько раз в соответствии с category.length). Однако я не знаю точной причины, но тот, который хранится в состоянии, является только последним вызовом API reponse

Также пробовали многие другие вещи, которые я упомянул выше, с не повезло.

...