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

时间:2016-04-24 14:51:23

标签: javascript jquery ajax reactjs

我遇到了freecodecamp的twitch tv api应用程序的问题。

我有一个带有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调用不是btw的问题。如果我在成功方法中记录数据,那么一切都是我喜欢的。

任何想法?

2 个答案:

答案 0 :(得分:2)

使用.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请求需要时间,浏览器只会同时执行有限数量的HTTP请求。特别是这种方法的一个问题是“temp”数组的顺序不一定与原始数组的顺序相匹配。也就是说,当该过程完成时,tempArray[2]可能包含也可能不包含来自STREAMER[2]的ajax调用的结果。无法保证HTTP请求将按照发出的顺序完成;事实上,如果你做的不止一些,那么它们很可能完全无序。

答案 1 :(得分:0)

简单解决方案

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

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内的setStateresolve()