【问题标题】:Redux thunk dispatch does not return errorRedux thunk dispatch 不返回错误
【发布时间】:2019-01-27 07:44:30
【问题描述】:

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

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

目前我包装了我的 fetch 以重用我在服务器 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 }
    })

那么我的动作创建者是这样的:

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()
        })

【问题讨论】:

    标签: redux promise redux-thunk


    【解决方案1】:

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

    当您在onRejected 中发现错误后,它会返回一个不再是错误的承诺(承诺的状态已完成且未被拒绝)。

    如果你想让 promise 到达 catch 块,你应该改变你的 action creator:

    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)
              }
            })
    

    这将返回一个被拒绝的promise,因此它将被catch块捕获。

    另外,你可以改变

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

    throw 'error'
    

    Promise.reject(data2)
    

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

    【讨论】:

      【解决方案2】:

      当你这样做时:

      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 函数的错误,然后您返回data2。这意味着您想用data2 返回一个 Promise 成功(解决)。 catch 也会发生同样的事情。

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

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

      第二种方式,如果你还想对之前的错误做点什么,你需要返回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)
          })
      

      【讨论】:

        猜你喜欢
        • 2021-04-26
        • 2017-10-31
        • 2017-04-30
        • 2017-06-09
        • 2021-06-03
        • 2020-04-16
        • 2021-08-11
        • 2017-12-27
        • 1970-01-01
        相关资源
        最近更新 更多