【问题标题】:Using Async and await with Fetch (in Actions of Redux) ReactJS将 Async 和 await 与 Fetch 一起使用(在 Redux 的操作中)ReactJS
【发布时间】:2019-06-03 23:20:24
【问题描述】:

我试图在单击按钮时一个接一个地调用多个 API。像这样的东西。然后路由到不同的路径。

 onRowClick = (id) => {
  this.props.selectQuestionnaire(id)
  this.props.getSpecificQuestionnaireAQ(id)
  this.props.getAQoptions(id)
  this.props.getAQResultarray(id)
  history.push('/answerques')
};

所有这些都被指定为 redux 层中的操作,我正在使用 fetch 库来进行这些 API 调用一个这样的操作的示例是:

export function getAQResultarray(aqid){
  return function(dispatch){
    console.log("fetching specific AQ")
    var myHeaders = new Headers();
    myHeaders.append('Accept' ,  'application/json');
    myHeaders.append('Content-Type' ,  'application/json');
    myHeaders.append('x-Auth-Token' ,  localStorage.getItem('authtoken'));

    const myInit = {
      headers: myHeaders,
      credentials : 'same-origin'
    };

    var url="http://10.00.000.00:000/abc/api/v1/"+aqid
    console.log(url);
    var myRequest = new Request(url)
    fetch(myRequest, myInit)
      .then((response) => {
        console.log("Response for aq responses  notfications : ",response)
        return response.json();
      })
      .then((tokenData) => {
        console.log("posting aq responses specific  : ",tokenData);
        dispatch({
        type : AQ_RESPONSEARRAY,
        payload : tokenData
      })})
      .catch((error) => {
        console.log(error);
      });
  }
};

如何使这段代码的行为如此,API 调用以同步方式发生?我的意思是,每个动作只有在前一个动作完成后才会被调用。

我听说过 promise,以及 async/await。哪个更容易实现?

【问题讨论】:

  • "每个动作只有在前一个动作完成后才会被调用。"你为什么需要这个?这些动作似乎是独立的。
  • 所以,我有一些基于这些响应呈现的组件(在 /answerques 内,我正在推送)。而且我需要在该组件呈现之前完成所有三个响应,目前我有一个稍微复杂的 componentDidupdate 与多个 if 条件,以查看这些是否返回了有效响应。但是,我正在寻找更好的解决方案

标签: reactjs redux react-redux fetch-api redux-thunk


【解决方案1】:

如果我正确地理解了您的问题,您只想链接最后一段代码,即重定向。虽然这些动作完全可以并行运行。为实现这一点,您的动作创建者应返回不破坏承诺链的承诺。

onRowClick = (id) => {
  // run all actions in parallel
  Promise.all([this.props.selectQuestionnaire(id)
    this.props.getSpecificQuestionnaireAQ(id)
    this.props.getAQoptions(id)
    this.props.getAQResultarray(id)])
  .then(() =>  history.push('/answerques'))
};

修复动作创建者从 thunk 返回承诺。

export function getAQResultarray(aqid){
  return function(dispatch){
    console.log("fetching specific AQ")
    var myHeaders = new Headers();
    myHeaders.append('Accept' ,  'application/json');
    myHeaders.append('Content-Type' ,  'application/json');
    myHeaders.append('x-Auth-Token' ,  localStorage.getItem('authtoken'));

    const myInit = {
      headers: myHeaders,
      credentials : 'same-origin'
    };

    var url="http://10.00.000.00:000/abc/api/v1/"+aqid
    console.log(url);
    var myRequest = new Request(url)

    // NB! return statement
    return fetch(myRequest, myInit)
      .then((response) => {
        console.log("Response for aq responses  notfications : ",response)
        return response.json();
      })
      .then((tokenData) => {
        console.log("posting aq responses specific  : ",tokenData);
        dispatch({
        type : AQ_RESPONSEARRAY,
        payload : tokenData
      })})
      .catch((error) => {
        console.log(error);
      });
  }
};

如果你真的想一个接一个地运行动作(但我怀疑你真的需要它)你最好至少在处理程序中坚持async/await 语法。但无论如何,你的动作创建者的 thunk 应该最终返回一个承诺。

onRowClick = async (id) => {    
  await this.props.selectQuestionnaire(id)
  await this.props.getSpecificQuestionnaireAQ(id)
  await this.props.getAQoptions(id)
  await this.props.getAQResultarray(id)
  history.push('/answerques')
};

【讨论】:

  • 好的,试试这个然后回来。
猜你喜欢
  • 2018-10-07
  • 1970-01-01
  • 2021-06-05
  • 2021-07-19
  • 2018-03-04
  • 2018-09-03
  • 1970-01-01
  • 1970-01-01
  • 2018-11-21
相关资源
最近更新 更多