使用异步方法反应可观察到的redux

时间:2018-10-23 11:22:12

标签: reactjs asynchronous redux observable

我正在尝试通过带有异步动作的react / redux实现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(),那么它将再次起作用。

有些事情我还不完全了解,我无法将所有事物变成可观察的,我需要继续使用异步的东西。

任何帮助都会很棒。

谢谢

1 个答案:

答案 0 :(得分:0)

  

我无法将一切变成可观察的,我需要继续使用异步内容。

您实际上可以并且应该将任何内容最终转换为可观察的。 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 });
       }
     })
   })