javascript - 如何使用 Promise.all 正确获取 React 应用程序的数据

标签 javascript reactjs typescript asynchronous promise

我正在开发一个 React 应用程序,我需要在组件安装时获取一些数据。由于我需要进行 3 个不同的调用,因此我认为最好使用 Promise.all 以便以并行方式执行此操作。这里的代码工作得很好,它完全按照我的意图去做,但是,修改代码的人将其标记为错误,并显示消息“您不会在此处返回 promise 。要么等待,要么 promise ,但不能两者兼而有之”。 ”。我实在不明白他说这话是什么意思。我只是一个初学者开发人员,他的经验比我丰富得多,所以我认为他是对的,而这段代码是错误的,但我就是不明白为什么。

async componentDidMount() {   
    const start = Date.now();

    // TODO: BUG! you are not returning the promise here! Either await or promise but not both!
    const promises = [this.fetchReports({}), this.fetchEntities(), this.fetchCodePulseRange()];

    await Promise.all(promises);
    console.log("Data fetching time: ", Date.now() - start)
    this.setState({ inited: true });
  }  

  async fetchEntities() {
    const res = await insightService.fetchEntities(this.props.profile.organisationId);
    this.setState({ allEntities: res, entityType: 'product' });
  }

  async fetchReports(entities: { [key: string]: string }) {
    const res = await insightService.fetchInsights(reports, entities, this.props.profile.organisationId, JSON.stringify(entities));
    this.setState({ reportsWithData: res });
  }

  async fetchCodePulseRange() {
    const res = await insightService.fetchCodePulseRange(this.props.profile.organisationId);
    this.setState({ codePulseRange: res });
  }

最佳答案

最好的办法是询问对方的意思。我看不出您将 Promise 放入数组中然后 awaiting Promise.all 存在任何问题,这样您就知道它们何时全部实现(或一个其中已被拒绝)。审阅者可能并不完全清楚 Promise.all 的作用以及为什么它即使在 async 函数中也有意义(正是出于您指定的原因:操作,然后等待它们全部完成,允许它们并行运行)。

存在一个问题,即您的代码中没有任何内容处理或报告提取操作中的错误。这可能就是他们试图间接指出的。 Promise 的规则之一是:要么处理错误,要么将 Promise 链传播到能够处理错误的地方。 React 不会处理来自 componentDidMount 的 promise 拒绝,因此您需要自己处理错误。

还会修改代码,以便您只进行一次状态更改,而不是四个状态更改:

componentDidMount() {   
    const start = Date.now();

    const promises = [this.fetchReports({}), this.fetchEntities(), this.fetchCodePulseRange()];
    Promise.all(promises)
    .then(([reportsWithData, allEntities, codePulseRange]) => {
        console.log("Data fetching time: ", Date.now() - start)
        this.setState({
            reportsWithData,
            allEntities,
            entityType: "product",
            codePulseRange,
            inited: true,
        });
    })
    .catch(error => {
        // ...handle/report error...
    });
    this.setState({ inited: true });
}  

fetchEntities() {
    return insightService.fetchEntities(this.props.profile.organisationId);
}

fetchReports(entities: { [key: string]: string }) {
    return insightService.fetchInsights(reports, entities, this.props.profile.organisationId, JSON.stringify(entities));
}

fetchCodePulseRange() {
    return insightService.fetchCodePulseRange(this.props.profile.organisationId);
}

但是如果您想保留增量更新(四个单独的状态更新),您可以这样做,只需确保处理 componentDidMount 中的错误以及使用这些 的任何其他地方>fetchXyz 操作。例如,如果您单独保留 fetchXyz 操作,则:

componentDidMount() {   
    const start = Date.now();

    const promises = [this.fetchReports({}), this.fetchEntities(), this.fetchCodePulseRange()];
    Promise.all(promises)
    .then(() => {
        console.log("Data fetching time: ", Date.now() - start)
        this.setState({ inited: true });
    })
    .catch(error => {
        // ...handle/report error...
    });
}  

async componentDidMount() {   
    const start = Date.now();

    try {
        const promises = [this.fetchReports({}), this.fetchEntities(), this.fetchCodePulseRange()];
        await Promise.all(promises);
        console.log("Data fetching time: ", Date.now() - start)
        this.setState({ inited: true });
    } catch (error) {
        // ...handle/report error...
    }
}  

我必须承认,我并不热衷于将 Promise 传递给不期望它们的事物(例如调用 componentDidMount 的 React 代码),但这是一个相对较小的风格事物,我不会不要像反馈中那样将其称为“错误”。

关于javascript - 如何使用 Promise.all 正确获取 React 应用程序的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66671540/

相关文章:

Javascript !和 !!差异

javascript - 使用d3.js修改c3.js图表

javascript - react-bootstrap 导入不正确

javascript - 在 Angular 的 innerHTML 中使用字符串插值

javascript - event.keyCode 返回土耳其字符 "ö"的逗号 (188) 的值

javascript - React + D3 强制布局 - 圆圈在渲染几秒后不再可拖动

ios - 你将如何在 react-native 中实现 pinch-zoom?

typescript - 如何用 Jest 模拟 Sequelize?

java - 有什么方法可以在 Java 中返回多态 this 吗?

javascript - 将(大量公式加载的)Excel 电子表格转换为用户友好的网络计算器