Реакция редукса, наблюдаемого асинхронным методом - PullRequest
0 голосов
/ 23 октября 2018

Я пытаюсь реализовать Observables с реакцией / редукцией с асинхронными действиями, вот код моего эпоса, пока все работает правильно:

export function requestDataEpic (action$, store) {    
   return action$.pipe(ofType(REQUEST_DATA),
     mergeMap(({ payload }) => {
        return Observable.ajax.get(`${API_URL}/${payload.userId}`)
    .flatMap((result) => {
       return Observable.of(requestDataSucess({ result }))
     })
     .catch((error) => {
       return Observable.of(requestDataFailure({ error }))
     })
   }),
   catchError((error) => {      
     alertError({ error })
     return empty()
   })
  )
}

Это работает отлично, как и ожидалось.

Теперь проблема возникает, когда я пытаюсь вызвать мою функцию getData (которая выполняет асинхронный вызов) вместо прямого вызова Observable.ajax.get .Я хотел бы вызвать эту функцию, которая будет проверять токен API, а затем обрабатывать вызов Observable.ajax, например:

export default async function getData ({ URL, userId }) {

  const { token } = await verifyToken()

  const params = {
    token,
    userId,
  }

  const query = Object.keys(params)
    .map((key) => key + '=' + params[key])
    .concat(fields)
    .join('&')

  return Observable.ajax.get(URL + query)
}

Таким образом, окончательный код будет выглядеть следующим образом:

export function requestDataEpic (action$, store) {    
  return action$.pipe(ofType(REQUEST_DATA),
    mergeMap(({ payload }) => {
      return getData(API_URL, payload.userId)
     .flatMap((result) => {
       return Observable.of(requestDataSucess({ result }))
      })
     .catch((error) => {
       return Observable.of(requestDataFailure({ error }))
     })
   }),
   catchError((error) => {      
     alertError({ error })
     return empty()
   })
 )

}

Я получаю (getData.default) (...) flatMap не является функцией

Если удалить асинхронное слово в объявлении функции + удалитьawait verifyToken (), затем он снова работает.

Есть вещи, которые я не до конца понимаю, я не могу превратить все в Observable, мне нужно продолжать использовать асинхронные вещи.

Любая помощьбыло бы здорово.

Спасибо

1 Ответ

0 голосов
/ 23 октября 2018

Я не могу превратить все в Observable, мне нужно продолжать использовать асинхронные вещи.

В действительности вы можете и должны конвертировать все в наблюдаемое в конце.flatMap не существует в обещании, поэтому есть ошибка.

getData не имеет смысла, потому что он смешивает обещания и наблюдаемые и возвращает обещание наблюдаемой.Один из них должен быть выбран, например:

async function getData ({ URL, userId }) {
  const { token } = await verifyToken()
  ...
  return Observable.ajax.get(URL + query).toPromise()
}

Обещания могут быть преобразованы в наблюдаемые с помощью операторов mergeMap / switchMap или from.Нет необходимости использовать flatMap, если вы уже используете обещания:

   return action$.pipe(ofType(REQUEST_DATA),
     mergeMap(async ({ payload }) => {
       try {
         const result = await Observable.ajax.get(`${API_URL}/${payload.userId}`)
         return requestDataSucess({ result });
       } catch (error) {
         return requestDataFailure({ error });
       }
     })
   })
...