Redux thunk dispatch 没有 return 错误

Redux thunk dispatch does not return error

我正在尝试 return 调度的承诺,以便我可以在我的反应组件中做这样的事情

this.props.dispatch(requestLogin(data))
  .then((res) => {
   Navigate.toHome()
}).catch((err) => {
  this.showErrorMessage()
})

目前我包装了我的提取以重用我在服务器上传递的常见内容 API 并放置一些日志以进行调试。我是这样做的:

export const query = (path, opts) => {

 // common config and boilerplates here
 // e.g add device id to every api request

 return fetch(opts.url, reqOpts)
    .then((response) => {

       console.log('response received') 

       if (response.ok) {
         return response.json()
       } else
          console.log('response not ok')})
    .then((respData) => {
        if (respData.status === true) {
          console.log('response success') 
          return respData
        } else {
          const errObj = respData
          errObj.server = true
          throw errObj
        }
    }).catch((err) => {
      console.log('error catched')
      if (err.server) {
        throw err
      }
      throw { status: false, errors: { error_code: 'ERR_FATAL', error_msg: 'Something went wrong.' }, err }
    })

那我的action creator是这样的:

export function requestLogin (data) {
  return function (dispatch) {
    const opts = {
      method: 'POST',
      body: data,
    }
    return query(Paths.OP_USR_LOGIN, opts)
        .then((data) => {
           data.TYPE = APP_LOGIN
           dispatch(resultData)
        },
        (data2) => {
          // the thrown error actually returns here
          // this returned value goes to the .then of the dispatch
          return data2
        },
        ).catch((err) => {
          // this is not executed
          return err
        })
  }
}

发生的事情是

this.props.dispatch(requestLogin(data))
          .then((res) => {
         // the error actually goes here
           Navigate.toHome()
        }
        (err) => {
         // not here
        }).catch((err) => {
        // or here
          this.showErrorMessage()
        })

首先,重要的是要了解您提供的第二个参数 then(onFulfilled, onRejected),即 onRejected,是要捕获的另一种语法,因此因为它是在动作创建器中的捕获之前编写的,所以您当查询函数抛出错误时到达那里。这就是为什么不执行 catch 块的原因。 (read about promise's then).

在您发现 onRejected 中的错误后,它 return 是一个承诺,它不再是一个错误(承诺的状态已实现而不是被拒绝)。

如果您希望 promise 到达 catch 块,您应该更改您的操作创建者:

return query(Paths.OP_USR_LOGIN, opts)
        .then((data) => {
           data.TYPE = APP_LOGIN
           dispatch(resultData)
        },
        (data2) => {
          // the thrown error actually returns here
          // this returned value goes to the .then of the dispatch
          return new Promise((resolve,reject) => {
            reject(data2)
          }
        })

这将 return 一个被拒绝的承诺,因此它将被 catch 块捕获。

另外,您可以更改

return new Promise((resolve,reject) => {
                reject(data2)
              }

throw 'error'

Promise.reject(data2)

如果您需要任何进一步的解释,请告诉我。

当你做的时候:

query(Paths.OP_USR_LOGIN, opts)
    .then((data) => {
       data.TYPE = APP_LOGIN
       dispatch(resultData)
    },
    (data2) => {
      // the thrown error actually returns here
      // this returned value goes to the .then of the dispatch
      return data2
    })
    .catch((err) => {
      // this is not executed
      return err
    })

实际上,你已经捕获了query函数的错误,然后你returndata2。这意味着你想要 return 与 data2 的 Promise 成功(解决)。同样的事情发生在 catch.

要修复它,您只需删除 (data2) => {}catch 块。

query(Paths.OP_USR_LOGIN, opts)
    .then((data) => {
       data.TYPE = APP_LOGIN
       dispatch(resultData)
    })

第二种方式,如果你还想对之前的错误做一些处理,需要return Promise.reject:

query(Paths.OP_USR_LOGIN, opts)
    .then((data) => {
       data.TYPE = APP_LOGIN
       dispatch(resultData)
    })
    .catch((err) => {
      // you can do something with error, and still return a promise.reject here
      console.log('I found an error here', err)
      return Promise.reject(err)
    })