react ajax : 多重嵌套获取 Get
react ajax : multiple nested fetch Get
有一个函数首先获取环境中的所有区域,然后当他为每个区域找到这些区域时,它将对边界点进行 api 调用。
所有提取都已执行,但问题是如果我尝试写出区域的 length 或尝试在第一次提取中 then做一个 .foreach 我得到 0.
我知道这是因为它异步运行并且在我执行 console.log 时尚未加载,但我认为它应该加载。这就是我们使用 .then 的原因,不是吗?等待数据加载完成。
要明确:我正在寻找一种方法让 zones.length 返回对象数组的实际长度并立即计算而不是 0 .我不知道如何:
这是代码。
getZones(){
var that = this;
var zones = new Array();
fetch('api/environment/zone/1').then(function(response){
response.json().then(function(data){
data.forEach(function(element){
zones[element.zoneID] = element;
zones[element.zoneID].points = [];
fetch('api/zone/point/'+element.zoneID).then(function(response){
response.json().then(function(data){
data.forEach(function(element){
zones[element.zoneID].points.push(element);
});
}); //closing of data inner fetch.
});
});
});
}).then(function(response){
console.log(zones); //this gives all zones
console.log(zones.length); //this one gives 0
//the for each is never executed because it's still 0.
zones.forEach(function(element){
console.log(element);
});
});
}
非常感谢快速 Reaction 和帮助。
对 fetch
returns 和 Promise
的调用,即 async
。所以你的第二个 .then
甚至在第一个然后完成的代码之前执行,因为你的第一个然后 contains
另一个 fetch
函数被调用,它是异步的。你可以有一个像下面这样的逻辑来等待,直到你得到所有的点数据并继续你的逻辑。
getZones(){
var that = this;
// var zones = new Array();
// this function gets called finally.
// Do what you want to do with zones and points here.
var gotAllZones = function(zones) {
console.log(zones); //this gives all zones
console.log(Object.keys(zones).length); //this one gives 0
Object.keys(zones).forEach(function(index){
console.log(zones[index]);
});
}
fetch('api/environment/zone/1').then(function(response){
response.json().then(function(data){
//decleare zones to be a object. Based on your code `zones` is not an array
var zones = {};
var pointsDone = 0; // declare how many points api has been completed. Initially its `0`
data.forEach(function(element){
zones[element.zoneID] = element;
zones[element.zoneID].points = [];
fetch('api/zone/point/'+element.zoneID).then(function(response){
response.json().then(function(innerData){
innerData.forEach(function(element){
zones[element.zoneID].points.push(element);
});
pointsDone++; //each time we are done with one. we increment the value.
// we check if we are done collecting all points data
// if so we can call the final function.
if(pointsDone === data.length) {
gotAllZones(zones);
}
}); //closing of data inner fetch.
});
});
});
})
}
最后我修的更漂亮了:
getZones2(){
var that = this;
var zones = [];
fetch('api/environment/zone/1')
.then(res => res.json())
.then((json) => {
Promise.all(
json.map(
element => fetch('api/zone/point/' + element.zoneID)
.then(res => res.json())
)
).then(datas => {
json.forEach((element, i) => {
zones[element.zoneID] = element
zones[element.zoneID].points = datas[i]
})
console.log(zones);
zones.forEach(function(response){
that.makeZone(response.name,response.zoneID,response.points);
})
})
});
}
有一个函数首先获取环境中的所有区域,然后当他为每个区域找到这些区域时,它将对边界点进行 api 调用。 所有提取都已执行,但问题是如果我尝试写出区域的 length 或尝试在第一次提取中 then做一个 .foreach 我得到 0.
我知道这是因为它异步运行并且在我执行 console.log 时尚未加载,但我认为它应该加载。这就是我们使用 .then 的原因,不是吗?等待数据加载完成。
要明确:我正在寻找一种方法让 zones.length 返回对象数组的实际长度并立即计算而不是 0 .我不知道如何:
这是代码。
getZones(){
var that = this;
var zones = new Array();
fetch('api/environment/zone/1').then(function(response){
response.json().then(function(data){
data.forEach(function(element){
zones[element.zoneID] = element;
zones[element.zoneID].points = [];
fetch('api/zone/point/'+element.zoneID).then(function(response){
response.json().then(function(data){
data.forEach(function(element){
zones[element.zoneID].points.push(element);
});
}); //closing of data inner fetch.
});
});
});
}).then(function(response){
console.log(zones); //this gives all zones
console.log(zones.length); //this one gives 0
//the for each is never executed because it's still 0.
zones.forEach(function(element){
console.log(element);
});
});
}
非常感谢快速 Reaction 和帮助。
对 fetch
returns 和 Promise
的调用,即 async
。所以你的第二个 .then
甚至在第一个然后完成的代码之前执行,因为你的第一个然后 contains
另一个 fetch
函数被调用,它是异步的。你可以有一个像下面这样的逻辑来等待,直到你得到所有的点数据并继续你的逻辑。
getZones(){
var that = this;
// var zones = new Array();
// this function gets called finally.
// Do what you want to do with zones and points here.
var gotAllZones = function(zones) {
console.log(zones); //this gives all zones
console.log(Object.keys(zones).length); //this one gives 0
Object.keys(zones).forEach(function(index){
console.log(zones[index]);
});
}
fetch('api/environment/zone/1').then(function(response){
response.json().then(function(data){
//decleare zones to be a object. Based on your code `zones` is not an array
var zones = {};
var pointsDone = 0; // declare how many points api has been completed. Initially its `0`
data.forEach(function(element){
zones[element.zoneID] = element;
zones[element.zoneID].points = [];
fetch('api/zone/point/'+element.zoneID).then(function(response){
response.json().then(function(innerData){
innerData.forEach(function(element){
zones[element.zoneID].points.push(element);
});
pointsDone++; //each time we are done with one. we increment the value.
// we check if we are done collecting all points data
// if so we can call the final function.
if(pointsDone === data.length) {
gotAllZones(zones);
}
}); //closing of data inner fetch.
});
});
});
})
}
最后我修的更漂亮了:
getZones2(){
var that = this;
var zones = [];
fetch('api/environment/zone/1')
.then(res => res.json())
.then((json) => {
Promise.all(
json.map(
element => fetch('api/zone/point/' + element.zoneID)
.then(res => res.json())
)
).then(datas => {
json.forEach((element, i) => {
zones[element.zoneID] = element
zones[element.zoneID].points = datas[i]
})
console.log(zones);
zones.forEach(function(response){
that.makeZone(response.name,response.zoneID,response.points);
})
})
});
}