【问题标题】:Promise.all() problem using setTimeout(), state not updating使用 setTimeout() 的 Promise.all() 问题,状态未更新
【发布时间】:2018-12-12 03:14:04
【问题描述】:

我有一个从cDM 调用的箭头函数,以使用setTimeout() 每20 秒检索一次计划的更新状态。

componentDidMount() {
    //get request to /schedules
    //update state with response data
    this.getUpdatedStatus();
}

/schedules 上的每个时间表如下所示:

"data": {
"id": "2147483605",
"selfUri": "/schedules/2147483605",
"type": "Schedule",
"status": "Pending",
}

所以在下面的方法中,每个schedule.selfUri 都被请求,我正在尝试更新每个计划的status

    getUpdatedStatus = () => {
//fetch updated status,
const schedules = this.state.schedules;
Promise.all(
  schedules.map(schedule =>
    axios({
      method: "get",
      url: schedule.selfUri,
    })
  )
)
  .then(response => {
    console.log(response);
    const isIncomplete = response.some(r => r.status !== "Complete");
    console.log(isIncomplete);
    if (isIncomplete) {
      this.timeout = setTimeout(() => this.getUpdatedStatus(), 20000);
    }
    this.setState(
      {
        scheduleStatus: isIncomplete ? "Pending" : "Complete",
      },
      () => {
        console.log(this.state.scheduleStatus);
        console.log(this.state.schedules);
      }
    );
  })
  .catch(error => console.log(error.response));

};

setTimeout 函数正在工作,并且每 20 秒请求一次检索可能的状态更新。对象响应最终返回complete 的状态,但该值未在我的表中重新呈现。我相信我的承诺链存在问题,使用 setTimeout 完成时不会更新我的 this.state.scheduleStatus。我附上了一个代码框,可以更好地了解我的问题。

Codesandbox

【问题讨论】:

  • 你能提供显示问题的工作小提琴吗? jsfiddle.net
  • 您应该做的第一件事是将<fieldset> 包装在<form> 元素中。这将允许 React 正确控制表单元素。接下来,似乎组件没有正确安装。
  • 接下来,您没有将scheduleStatus 声明为状态属性,而是尝试使用它。所以将scheduleStatus 声明为状态属性。最后,Axios 调用返回的数据是一个 HTML 页面...不是数据。
  • 我认为问题实际上可能出在“const isIncomplete = response.some(r => r.status !== "Complete");"这似乎是在查看 response.status,即 http 状态。由于这始终是一个 http 状态代码,它永远不会等于“完成”,因此始终返回 true。
  • @RyanGibbs 你和我得出了完全相同的结论 :)

标签: javascript reactjs promise


【解决方案1】:

我认为您的问题与承诺链或使用 setTimeout() 无关。我认为这是由于错误地获取了isIncomplete 标志的值,它总是被设置为true

您通过以下行设置此值:

const isIncomplete = response.some(r => r.status !== "Complete")

我认为这里的问题是您期望响应对象是您指定的数据,其中包含带有字符串值的status 属性,而实际上它是 Axios 返回的响应对象,其中statusproperty 是实际响应的状态码(成功时为200)。因此,isIncomplete 始终为true,因为r.status 永远不会等于"Complete"

您的数据可以在data 属性中找到,因此上述行应如下所示:

const isIncomplete = response.some(r => r.data.status !== "Complete")

【讨论】:

  • 所以isIncomplete 标志现在基于r.data.status 工作,当status = "Complete" 时它变为false,但它仍然没有在我的表中呈现Complete
  • 知道为什么status 的更新值没有重新渲染吗?
  • @DJ2 那么一定有其他东西阻止重新渲染。您的代码在此更改后看起来很好,当我尝试它时(对请求进行模拟),它确实正确更新了文本。
  • 好吧,我发现了这个问题,我在 setTimeout 方法之后记录了一个状态值,该方法在调用 setState 之前引发了异常。
猜你喜欢
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-24
  • 1970-01-01
  • 2021-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多