1

This code works as expected now, but as my app loads, I am doing API calls to gather data from 8 different tables. I notice that all the calls are happening almost simultaneously and out of order. Order doesn't actually matter as long as they all happen, as I'm just loading data.

I'm just trying to think are there drawbacks to doing it this way that I need to watch out for, and if so, how do I make the loop wait until the function is finished, to then move onto the next iteration through the loop?

componentDidMount() {
    const tableSections = [
      'audit_general',
      'audit_culture',
      'audit_performance',
      'audit_policies',
      'audit_risk',
      'audit_strategy',
      'audit_rewards',
      'audit_workforce'
    ];
    for (let i = 0; i < tableSections.length; i++){
      this.grabTableData(tableSections[i]);
    }
  }

  grabTableData(tableName) {
    fetch(API_URL + `/responses/${tableName}/${this.props.employeeId}`)
      .then((res) => {
        if (!res.ok) {
          throw new Error();
        }
        return res.json();
      })
      .then((result) => {
        this.setState({
          ...result[0],
        });
      })
      .catch((error) => {
        console.log(error);
      });
  }
Adam Norton
  • 512
  • 2
  • 5
  • 21

2 Answers2

1
componentDidMount() {
    const tableSections = [
      'audit_general',
      'audit_culture',
      'audit_performance',
      'audit_policies',
      'audit_risk',
      'audit_strategy',
      'audit_rewards',
      'audit_workforce'
    ];
    for (let i = 0; i < tableSections.length; i++){
      this.grabTableData(tableSections[i]);
    }
  }

  async grabTableData (tableName) {
    await fetch(API_URL + `/responses/${tableName}/${this.props.employeeId}`)
      .then((res) => {
        if (!res.ok) {
          throw new Error();
        }
        return res.json();
      })
      .then((result) => {
        this.setState({
          ...result[0],
        });
      })
      .catch((error) => {
        console.log(error);
      });
  }
Rob Terrell
  • 2,398
  • 1
  • 14
  • 36
0

The only real drawback would be if you have a lot of tableSections, then under some circumstances, you'd be making lots of requests at once, which could

  • put more load onto the server at once than it's expecting, and/or
  • saturate your network connection with the response (if the response payload is large)

Making large numbers of individual requests at once can also sometimes make making additional requests more difficult temporarily. (This can be somewhat mitigated if the server uses H2 protocol, IIRC) This may be due to an OS limit or a browser limit too.

As a rule of thumb, I think limiting the number of concurrent requests to no more than 5 or 6 at once is a good strategy. (Though, you only have 8 elements in the array here, which isn't too terrible. If it were 15+, it'd definitely be something to worry about)

how do I make the loop wait until the function is finished, to then move onto the next iteration through the loop?

If you really want to wait in serial, you can await each call:

componentDidMount() {
  this.getInitialState()
    .catch(handleErrors);
}
async getInitialState() {
    const tableSections = [
      'audit_general',
      'audit_culture',
      'audit_performance',
      'audit_policies',
      'audit_risk',
      'audit_strategy',
      'audit_rewards',
      'audit_workforce'
    ];
    for (let i = 0; i < tableSections.length; i++){
      await this.grabTableData(tableSections[i]);
    }
  }
}

But simply limiting the number of currently active connections to 5 or so would probably be a better choice - the script would finish more quickly without much chance of possibly overloading something. For a possible implementation of this idea, see here.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320