Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
886 views
in Technique[技术] by (71.8m points)

javascript - How to get xmlhttprequest results in a for loop

Good day all, Please i'm trying to get the latency values of a ping using xmlhttprequest in a for loop for five consecutive latencies that will be stored in an global array in a react native application, after which when the for loop finishes, other codes can now execute, but it seems that the whole code just runs through without getting the array values from the initial for loop and the final result comes out as 0, then later, I start getting the array values due to the result of the xmlhttprequest. How can I ensure that I get the latency results first before now executing the remaining code. My code is below:

let latencies = [];

class App extends Component {

 startScan = () => {
   this.setState({
     scanning: true,
   }); 

   this.getJitter();
 }

 getPing = () => {
  var request = new XMLHttpRequest();
  var startTime = new Date();
  request.open(
    'GET',
    'http://dummy.restapiexample.com/api/v1/employees',
    true,
  );
  request.send();

  request.onreadystatechange = (e) => {
  if (request.readyState == 4 && request.status == 200) {
    var endTime = new Date();
    var ping = endTime.getTime() - startTime.getTime();
    this.setState({ping: ping});
    latencies.push(ping);
    console.log('ping:', ping);
    console.log(latencies);
    return ping;
   }
  };
 };

 getJitter = () => {
   for(var i=0; i<5; i++){
     this.getPing();
   }

  //Get each latency difference
  var total1 = 0;
  for (var i = 0; i < latencies.lenght; i++) {
    if (typeof latencies[i] === 'number') {
      console.log(latencies[i]);
      total1 += latencies[i + 1] - latencies[i];
      console.log(total1);
    }
  }

  var jitter = total1 / (latencies.length - 1);
  console.log(jitter); //this comes out as 0
  latencies = [];
 };

   render() {
     return (
       ...
       <Button title="Scan" onPress={this.startScan} />
     )
   };
 }

Thanks

Tim


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is that the XMLHttpRequest is asynchronous and will allow other code to run while it is trying to fetch the resource. The solution to this is to await each request and then move on to the next block.

I've switched the XMLHttpRequest for the Fetch API. fetch returns a Promise which you can await and wait for it to finish.

class App extends Component {

  startScan = () => {
    this.setState({
      scanning: true,
    }); 

    this.getJitter().then(() => {
      this.setState({
        scanning: false,
      });
    });
  }

  getPing = async () => {
    const startTime = new Date();
    await fetch('http://dummy.restapiexample.com/api/v1/employees');
    const endTime = new Date();
    const ping = endTime.getTime() - startTime.getTime();
    this.setState({ ping });
    return ping;
  }

  getJitter = async () => {
    const latencies = [];
    for (let i = 0; i < 5; i++){
      const ping = await this.getPing();
      latencies.push(ping);
    }

    //Get each latency difference
    let total1 = 0;
    for (let i = 0; i < latencies.length; i++) {
      if (typeof latencies[i] === 'number') {
        console.log(latencies[i]);
        total1 += latencies[i + 1] - latencies[i];
        console.log(total1);
      }
    }

    const jitter = total1 / (latencies.length - 1);
    console.log(jitter); //this comes out as 0
  };

  render() {
    return (
      <Button title="Scan" onPress={this.startScan} />
    )
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...