ReactJS:在带有 ajax 调用的 .map() 语句完成后执行代码

ReactJS: execute code after .map() statement with ajax call in it is finished

本文关键字:语句 代码 执行 map ajax 调用 ReactJS      更新时间:2023-09-26
我遇到了一个

问题,我的 twitch TV api 应用程序用于 freecodecamp。

我有一个带有 ajax 调用的 .map() 语句。我把从调用中获得的数据推送到一个数组中。

我想在整个 .map() 循环完成后将应用程序的状态设置为数组,但不知何故,当我在 .map() 之外访问它时,数组总是空的

这是我尝试过的代码。

getData() {
  let tempArray= [];
  let self = this;
  STREAMER.map(function(streamer, i) {
    $.ajax({
      url: URL + streamer,
      success: (data) => {
        tempArray.push(data);
      },
      dataType: "jsonp"
    })
  });
  this.setState({data: tempArray});
}

我感觉问题是 ajax 调用是异步 obv。但我认为,由于我在 .map() 循环之外调用 this.setState() 方法,它应该是同步的,所以一切都应该没问题,但事实并非如此。

顺便说一句,Ajax调用不是问题。如果我将数据记录在成功方法中,一切都是我喜欢的。

有什么想法吗?

使用.map()调用返回所有$.ajax()调用的承诺。然后,您可以使用$.when()等待它们完成:

getData() {
  let tempArray= [];
  let self = this;
  $.when.apply($, STREAMER.map(function(streamer, i) {
    return $.ajax({
      url: URL + streamer,
      success: (data) => {
        tempArray.push(data);
      },
      dataType: "jsonp"
    })
  }).then(function() {}
    self.setState({data: tempArray});
  });
}

返回的承诺将被收集到一个数组中,由 .map() .然后返回的数组通过 .apply() 传递到 $.when() 中。这将管理等待所有承诺,并且您的.then()回调将在全部完成后调用。

如果可能的话,我建议您研究在服务器上进行迭代工作的可能性,并提供一个处理一组项目并返回聚合结果的单个HTTP API。HTTP 请求需要时间,浏览器只会同时执行有限数量的请求。这种方法的一个特别问题是"temp"数组的顺序不一定与原始数组的顺序匹配。也就是说,当该过程完成时,tempArray[2]可能包含也可能不包含 ajax 调用 STREAMER[2] 的结果。 无法保证 HTTP 请求将按发出顺序完成;事实上,如果你做的不止几个,那么它们很可能会乱序完成。

简单的解决方案

setState()函数应在异步 ajax 请求的成功回调中调用。

getData() {
  let tempArray= [];
  let self = this;
  STREAMER.map(function(streamer, i) {
    $.ajax({
      url: URL + streamer,
      success: (data) => {
        tempArray.push(data);
        if(i === STREAMER.length - 1) {
          self.setState({data: tempArray});
        }
      },
      dataType: "jsonp"
    })
  });
}

使用承诺

当所有 ajax 请求都成功时,解析Promise并在 resolve()setState