【问题标题】:How do I return a promise in a redux action dispatch call so I can chain .then blocks?如何在 redux 操作调度调用中返回一个承诺,以便我可以链接 .then 块?
【发布时间】:2019-07-03 05:40:51
【问题描述】:

我正在使用 react-native 和 redux 创建一个应用程序。我的应用程序应该向 firebase rest api 发送请求以取回用户的待办事项。在我的 react-native 应用程序中,我通过在 react-native 组件的连接部分中传递的 redux 函数获得此响应。我想在调用我的函数后立即链接一个 .then 块。

我尝试创建一个承诺并在我的操作中返回它,但它在链接 .then / .catch 时会自动解决一个错误 我也试过在不创建承诺的情况下做同样的事情。

这是我的行动:

export const fetchHomework = () => {
  return (dispatch, getState) => {
      dispatch(uiStartLoading());
      dispatch(uiStartFetchingHomework());
      dispatch(authGetToken())
      .catch(err => {
        dispatch(errHandler(err))
      })
      .then(token => {
        const uid = getState().userid;

        fetch(restAPI)
        .catch(err => {
          dispatch(errHandler(err));
        })
        .then(res => res.json())
        .then(response => {
          dispatch({
            type : 'SET_HOMEWORK_FOR_AGENDA',
            homework : response
          })
          dispatch(uiStopLoading());
          dispatch(uiStopFetchingHomework());
        })
        .catch(err => {
          dispatch(errHandler(err));
          dispatch(uiStopLoading());
          dispatch(uiStopFetchingHomework());
        })

      })
      dispatch(uiStopLoading());
      dispatch(uiStopFetchingHomework());
  }
}

注意:rest api替换为rest api的url 这里是我获取这些数据的地方:

this.setState({refreshing: true});
this.props.retrieveHomework();
this.setState({refreshing: false, firebaseItems : this.props.homework});
this.loadItems(this.state.selectedDay);

(刷新时在函数中调用)

我希望当我在retrieveHomework 之后链接一个.then 块时,then 块会等待函数完成然后运行里面的代码,但这不是正在发生的事情。发生的情况是它要么跳过 then 块,要么抛出 catch 块捕获的错误。

编辑: this.props.retrieveHomework 是一个指向异步操作的函数,因为我使用的是 redux thunk。

【问题讨论】:

  • 我是否正确 props.retrieveHomework 指的是 fetchHomework 异步操作调度程序? redux-thunk 被使用了吗?
  • @skyboyer 是的,你是对的。我会将其添加到我的问题中以进行澄清

标签: reactjs react-native promise


【解决方案1】:

您需要将所有要等待运行的代码移动到.then

this.props.retrieveHomework()
  .then(() => {
    this.setState({refreshing: false, firebaseItems : this.props.homework});
    this.loadItems(this.state.selectedDay); // If this is async, you need to `return` it here as well
  });

【讨论】:

  • 嘿,马特。这确实发生了,但提出了另一个问题。由于我使用的是异步的 redux thunk,因此我的操作调用了一个同步函数来设置状态中的数据,并且异步函数在同步函数完成之前返回。这意味着当我调用 .then 时,我没有得到更新的状态,因为设置它的同步函数还没有完成。如何在返回异步函数/调用 .then 之前确保同步函数返回?
  • 问题是,React.Component#setState 也是异步的。这就是为什么建议使用function作为第一个参数调用它的原因,比如this.setState(prevState => newState),顺便解决了执行顺序的问题。
  • @rml 我确实明白这一点,但我认为我的问题令人困惑,因为我没有提供代码。我的意思是我调用了一个reducer 来在异步调度中设置我的状态,并且reducer 在异步调用之前没有完成,所以它不会及时更新状态。如何使我的异步函数在我设置状态之前不会返回?
  • 如果它很容易出现竞争条件,我可能会开始重新考虑围绕这个问题的整个状态管理。 ? 你有没有想过将整个 store 更新包装到一个新的 Promise 中,并且只在这个 Promise 解决时更新组件状态?
  • 我认为@rml 的建议是这样的:this.setState({refreshing: false, firebaseItems : this.props.homework}, () => this.loadItems(this.state.selectedDay)); 虽然setState 确实将回调函数或对象作为其第一个参数,但如果您是引用,则只需要使用回调this.state 在新的状态值中。 setState 还接受第二个参数,这是一个在 setState 完成后运行的函数,因为正如 @rml 所指出的,setState 本身是异步的
猜你喜欢
  • 2017-09-15
  • 2020-08-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-20
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多