如何在for循环中获取xmlhttprequest结果

How to get xmlhttprequest results in a for loop

大家好, 请尝试在 for 循环中使用 xmlhttprequest 获取 ping 的延迟值,连续五个延迟将存储在反应本机应用程序的全局数组中,之后当 for 循环完成时,其他代码现在可以执行,但似乎整个代码只是运行而没有从初始 for 循环中获取数组值,最终结果为 0,然后由于 xmlhttprequest 的结果,我开始获取数组值。我如何才能确保在执行剩余代码之前首先获得延迟结果。我的代码如下:

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} />
     )
   };
 }

谢谢

蒂姆

问题是 XMLHttpRequest 是异步的,并且在尝试获取资源时将允许其他代码 运行。解决方案是等待每个请求,然后继续下一个块。

我已经将 XMLHttpRequest 换成了 Fetch APIfetch returns 一个 Promise 你可以 await 并等待它完成。

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} />
    )
  }
}