我已经阅读了很多答案,但在这种情况下我不明白如何解决这个问题。
我有一系列积分和外部网站,我可以确定这点是在陆地还是在海上。问题是for
循环不等待XHR请求。
var points = [
[90, 120],
[80, 120],
[70, 120]
];
var land_or_sea = [];
for(var x= 0; x < points.length; x++) {
var lat_string = points[x][0];
var lng_string = points[x][1];
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (this.readyState === 4 && this.status === 200){
var obj = JSON.parse(this.responseText);
if (obj.water === true){
land_or_sea.push(x + 1);
}
}
}
xhr.open("GET", "https://api.onwater.io/api/v1/results/" + lat_string + "," + lng_string, true);
xhr.send();
}
如果点数在海上但由于for循环不等待,我应该添加land_or_sea
的索引,如何看到points
是一个空数组。
我希望你能帮助我。谢谢!
答案 0 :(得分:1)
我认为你最好的举措是避免这么多的api请求并创建一个api请求来处理坐标列表。但我猜这个api不支持它。
你有没有检查api是否正常,因为我试过了它给了我一个假水,一个空和一个500错误告诉我太多的请求错误。
另一个好处是使用xhr.onload方法,因为每次移动为onreadystatechange定义的函数时都会出现问题,x变量递增到3,因此对于每个后续的readystatechange(例如最终响应),你都会被保留x = 3,因为闭包保持指针,而不是定义时的值。因此,如果这样可行,它将使用值4填充数组,因为您将x + 1设置为[4,4,4]。
要将其包装起来,请使用onload而不是onreadystatechange并密切关注429/500错误。希望这会有所帮助。
答案 1 :(得分:0)
您可以创建递归函数,而不是使用for循环。
您可以将数组索引初始化为0并将其传递给函数。成功响应后,再次使用递增的数组索引调用相同的函数。到达array.length
例如:
var points = [
[90, 120],
[80, 120],
[70, 120]
];
var arrIndex = 0;
var land_or_sea = [];
function callAjaxFunc(arrIndex){
var lat_string = points[arrIndex][0];
var lng_string = points[arrIndex][1];
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (this.readyState === 4 && this.status === 200){
var obj = JSON.parse(this.responseText);
if (obj.water === true){
land_or_sea.push(x + 1);
if (arrIndex < points.length){
arrIndex++;
callAjaxFunc(arrIndex);
}
}
}
}
xhr.open("GET", "https://api.onwater.io/api/v1/results/" + lat_string + "," + lng_string, true);
xhr.send();
}
callAjaxFunc(arrIndex);
答案 2 :(得分:0)
如果您有ES7支持,可以将整个代码包装在异步函数中,只需等待结果即可。创建一个承诺并像这样使用它:(再次,这仅适用于您支持ES7 )
(async () => {
var points = [
[90, 120],
[80, 120],
[70, 120]
];
var p = (lat_string, lng_string) => new Promise(res => {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(this.readyState === 4 && this.status === 200){
res(JSON.parse(this.responseText));
}
}
xhr.open("GET", "https://api.onwater.io/api/v1/results/" + lat_string + "," + lng_string, true);
xhr.send();
})
var land_or_sea = [];
for(var x= 0; x < points.length; x++) {
var lat_string = points[x][0];
var lng_string = points[x][1];
var obj = await p(lat_string, lng_string)
if(obj.water === true) {
land_or_sea.push(x + 1);
}
}
})()
答案 3 :(得分:-1)
您正在寻找的是Synchrounous xhr请求。
XMLHttpRequest.open()方法的完整语法如下:
XMLHttpRequest.open(method, url, async, user, password)
您可以将“async”请求参数设置为“false”。如果此值为false,则send()方法在收到响应之前不会返回。