【问题标题】:Redux-observable with async method带有异步方法的 Redux-observable
【发布时间】:2019-03-27 14:48:06
【问题描述】:

我正在尝试使用带有异步操作的 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(),那么它会再次起作用。

有些东西我不完全理解,我不能把所有东西都变成 Observable,我需要继续使用异步的东西。

任何帮助都会很棒。

谢谢

【问题讨论】:

    标签: reactjs asynchronous redux rxjs6 redux-observable


    【解决方案1】:

    我不能把所有东西都变成 Observable,我需要继续使用异步的东西。

    您实际上可以并且应该最终将任何东西转换为可观察的。 flatMap 在 Promise 中不存在,因此存在错误。

    getData 没有意义,因为它混合了 Promise 和 observables 并返回一个 observable 的 Promise。必须选择其中之一,例如:

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

    可以使用 mergeMap/switchMap 运算符或 from 将 Promise 转换为 observables。如果您已经在使用 Promise,则无需使用 flatMap

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

    【讨论】:

    • 在操作中检测到​​不可序列化的值
    • 这意味着结果没有被正确处理。在上面的代码中,它取决于requestDataSucess 的工作方式。 sn-p 错过了toPromise,已修复。如果问题仍然存在,请考虑提出一个反映您的问题的问题。
    • 当我将异步函数传递给 mergeMap 时,我收到此错误。当我删除异步时,一切正常。但我需要一个异步函数,因为我使用 AsyncStorage
    猜你喜欢
    • 1970-01-01
    • 2019-12-09
    • 1970-01-01
    • 1970-01-01
    • 2018-02-15
    • 2019-02-01
    • 2020-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多