首页 > 解决方案 > 异步/等待同步函数改变反应状态

问题描述

我在 React 中遇到了async/await函数和更改状态的问题。这是我的异步功能,通过单击按钮触发:

async startNewEntry() {
    this.addIssue();
    let issue_id;
    console.log(this.state.timeEntry, "started_timeEntry")
    if (this.state.timeEntry?.issue?.id) {
      issue_id = this.state.timeEntry?.issue?.id;
    } else {
      issue_id = (await this.issueService.list()).data[0]?.id;
    }
    const { data } = await this.timeEntryService.create({
      comments: this.state.timeEntry.comments,
      issue_id,
      spent_on: moment(new Date()).format("YYYY-MM-DD"),
      hours: 0.01,
      activity_id: this.localStorageService.get("defaultActivityId")
    });

在这个函数中,我使用this.addIssue了,它使用this.createIssue了,它改变了我的类组件状态:

addIssue() {
    this.projectService.list([]).then(response => {
      response.data = response.data.filter((x: any) => x.status === 1);
      this.setState(
        {
          activeProjects: response.data
        },
        () => {
          this.createIssue();
        }
      );
    });
  }
  createIssue() {
    this.issueAddService
      .create({
        project_id: this.state.activeProjects[0].id,
        tracker_id: trakerId,
        priority_id: priorityId,
        subject: this.state.timeEntry.comments,
        description: this.state.timeEntry.comments
      })
      .then(response => {
        let timeEntry = this.state.timeEntry;
    timeEntry.issue = response.data;
    this.setState({
      timeEntry
    });

      })
      .catch(error => {
        console.log("error", error);
      });
  }

如您所见,在我的异步函数中,我有了新的状态,但实际上异步函数在我的this.addIssue函数之前工作。我知道这个问题可能有点怪异,但谢谢转发!

标签: javascriptreactjstypescript

解决方案


如果您想startNewEntry等到完成其工作后再addIssue做它的工作,您需要:

  1. 在完成addIssue工作时返回一个它履行的承诺,并且
  2. await调用时使用:await this.addIssue();

如果您需要startNewEntry查看更新后的状态,addIssue则需要从状态完成处理程序回调中实现 的承诺,如下所示:

addIssue() {
  // *** Return the promise chain to the caller
  return this.projectService.list([]).then(response => {
    response.data = response.data.filter((x: any) => x.status === 1);
    // *** Create a new promise
    return new Promise(resolve => {
      this.setState(
        {
          activeProjects: response.data
        },
        () => {
          this.createIssue();
          resolve(); // *** Fulfill the promise
        }
      );
    });
  });
}

通常,new Promise这是一种反模式,尤其是当您有另一个可以链接的承诺时。但是在这种情况下,由于您需要等待来自setState(未启用承诺)的回调,因此它是合适的。(


请注意对这个问题的评论。我认为你正在设置一个无限循环......


推荐阅读