我遇到了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的问题。如果我在成功方法中记录数据,那么一切都是我喜欢的。
任何想法?
答案 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
内的setState
和resolve()
。