【问题标题】:Call asynchronous interdependent Redux Actions one after the other一个接一个地调用异步相互依赖的 Redux Actions
【发布时间】:2017-10-06 02:55:38
【问题描述】:

在我的一个 React 组件中,我有以下方法:

  save() {
    var arrLength = this.state.arr.length;
    if(arrLength > 1) {

      var start = this.state.arr[arrLength-2];
      var end = this.state.arr[arrLength-1];


      this.props.updateItemAudio(start,end);
      this.props.saveItemToDisk();
      this.props.getNextItem();
    }
    else {
      console.log("Array not long enough yet");
    }
  }

重要的是:

  this.props.updateItemAudio(start,end);
  this.props.saveItemToDisk();
  this.props.getNextItem();

我需要等待第一个函数调用完成,然后再执行第二个,这与第三个相同。我怎样才能做到这一点?我听说有这个新的async / await syntax,我可以在这里使用它吗?我不希望将回调函数传递给这些操作。

编辑:我的方法不返回承诺,它们是正常的 Redux 操作。

【问题讨论】:

  • 这三个函数是否返回承诺?
  • 不,但你提到它很好,我编辑了我的问题。这三个函数只是“正常”的 redux 操作。
  • 或者您可以在这些单独的动作创建者内部执行它们,即在 updateItemAudio 动作完成后运行 saveItemToDisk 并在完成后运行 getNextItem

标签: javascript reactjs asynchronous redux async-await


【解决方案1】:

如果你的方法返回你可以使用的承诺:

async save() {
 await this.props.firstMethod();
 await this.props.secondMethod();
 await this.props.thisMethod();
}

文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

你的捆绑器或其他任务运行器应该编译 EcmaScript7 记住这一点

【讨论】:

  • 它不返回一个promise,它是一个普通的redux action。
  • 然后你可以在redux操作中使用这个语法:myReduxAction() { return (dispatch) => { return new Promise((resolve, reject) => { resolve(); //call resolve if you get response or your action ended }) } }更好的语法pastebin.com/7xkJieb4
【解决方案2】:

您可以在第一个动作中一个接一个地执行它们,即:

updateItemAudio = async (start, end) => {

  return (dispatch) => {

     try {

       // updateItemAudio stuff...
       let resultTwo = await saveItemToDisk();
       let resultThree = await getNextItem();

       // now all 3 executed in order

     } catch (err) {
       console.log(err);
  }

}

【讨论】:

    【解决方案3】:

    纯 redux 不允许您以干净的方式在另一个动作之后调度一个动作。

    我建议为此使用 3rd 方库,例如 redux-observableredux-saga。它们非常适合您的用例。

    你可以通过这种方式使用redux-observable解决这个问题:

    const myEpic = combineEpics(
      // listening to UPDATE_ITEM_AUDIO action type and dispatching saveItemToDisk() action after it
      action$ => action$.ofType(UPDATE_ITEM_AUDIO).map((action) => saveItemToDisk()),
      // the same as above, but listening for SAVE_ITEM_TO_DISK, and dispatching getNextItem() action
      action$ => action$.ofType(SAVE_ITEM_TO_DISK).map((action) => getNextItem())
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-17
      • 1970-01-01
      • 2020-09-17
      • 1970-01-01
      • 1970-01-01
      • 2016-05-12
      • 2017-10-04
      • 2020-11-15
      相关资源
      最近更新 更多