Redux 等待异步 thunk 继续进行

Posted

技术标签:

【中文标题】Redux 等待异步 thunk 继续进行【英文标题】:Redux await async thunk keeps going 【发布时间】:2019-03-02 18:25:03 【问题描述】:

我目前正在使用 redux / redux-thunk 像这样使用 api-sauce 获取用户

let authToken = await AsyncStorage.getItem('@TSQ:auth_token')

if (authToken) 
  store.dispatch(fetchUser(authToken))
  console.log('show login screen')
  // dont worry, if the token is invalid, just send us to onboarding (api determines this)
  loggedInView()
 else 
  Onboarding ()


....

export const fetchUser = authToken => async dispatch => 
  console.log('dispatching auth token')

  console.log('here goes request')
  let res = await api.get(`/auth/$authToken`);

  if (res.ok) 
    console.log('have the user')
    dispatch(
      setUser(res.data)
    )
   else 
    dispatch(
      type: 'SET_USER_DEFAULT'
    )

运行此代码时,用户仍在加载,console.logs 不按顺序

`dispatching auth token`
`here goes request`
`show login screen`

为什么会这样?

【问题讨论】:

【参考方案1】:

这是因为对store.dispatch(fetchUser(authToken)) 的实际调用是同步的——dispatch() 方法is not asynchronous,因此在执行fetchUser() 方法后将立即发生日志记录“显示登录屏幕”。

如果您希望在网络请求返回响应后执行loggedInView()(即调用异步方法api.get()),那么您可以考虑通过以下方式重构您的代码:

if (authToken) 
  store.dispatch(fetchUser(authToken))
  // Remove navigation from here
 else 
  Onboarding ()

然后:

export const fetchUser = authToken => async dispatch => 
  console.log('dispatching auth token')

  console.log('here goes request')
  let res = await api.get(`/auth/$authToken`);

  if (res.ok) 
    console.log('have the user')

    // Occurs after network request is complete    
    console.log('show login screen')

    // Add navigation here to go to logged in view now that request is complete
    loggedInView()

    dispatch(
      setUser(res.data)
    )
   else 
    dispatch(
      type: 'SET_USER_DEFAULT'
    )

希望这会有所帮助!

【讨论】:

以上是关于Redux 等待异步 thunk 继续进行的主要内容,如果未能解决你的问题,请参考以下文章

Redux thunk:如何等待异步操作的完成

Redux thunk:等待异步函数调度

React + redux + axios + thunk,等待interceptors.response 刷新token

Redux-thunk 调度一个动作并等待重新渲染

类型上不存在属性 - redux-thunk 等待调度

javascript - redux thunk 不等待任何承诺