React Native 使用 for 循环内的 fetch
在我的 React Native 应用中,我有一个对象数组,每个对象都有 3 个属性:地址、纬度和经度。纬度和经度最初为空,因此我使用 Google API 进行反向地理编码。由于它是一个数组,因此我在数组内循环并获取 Google URL 以从给定地址获取纬度和经度。但是当我尝试在对象中保存纬度和经度时,出现错误:
TypeError: undefined is not an object (evaluating: locations[i].latitude = responseJson.results[0].geometry.location.lat)
这是我的代码:
for (var i = 0; i < locations.length; i++){
if (locations[i].address){
var googleRequestUrl = this.state.GoogleAPIUrl + locations[i].address;
fetch(googleRequestUrl)
.then((response) => response.json())
.then((responseJson) => {
locations[i].latitude = responseJson.results[0].geometry.location.lat;
locations[i].longitude = responseJson.results[0].geometry.location.lng;
})
.catch((error) => {
console.warn(error);
})
.done();
}
}
我使用的谷歌 API 是:“ https://maps.googleapis.com/maps/api/geocode/json?address= ”
我已经使用 response.text() 检查过是否收到了响应:它给出了完整的响应,包括纬度和经度。
我不明白为什么会出现这个错误,我做错了什么?在循环中进行提取有什么问题吗?还是其他问题?
任何建议或更好的解决方案都值得赞赏
可能您的某个地址无法正确地理编码,并且您正尝试访问响应对象上不存在的结果。
我会检查结果是否存在并继续执行。
const result = responseJson.results[0];
if (result) {
locations[i].latitude = result.geometry.location.lat;
locations[i].longitude = result.geometry.location.lng;
}
此代码:
.then((responseJson) => {
locations[i].latitude = responseJson.results[0].geometry.location.lat;
locations[i].longitude = responseJson.results[0].geometry.location.lng;
})
不会执行您想要的操作。
由于此代码异步运行,它将使用在执行时找到的
i
的值。当您从服务器收到响应时,您的
for
循环将已经完成执行。for 循环末尾的
i
值是什么?它将是 4。
因此,您将尝试将值(对于每个提取)存储在未定义的
locations[4]
中。
要解决此问题,您可以做几件事:
1. 如果您使用的是 ES6,最简单的方法是在 for 循环中声明一个等于循环变量的常量。这基本上会在索引上创建一个闭包,以允许您稍后引用正确的值。它看起来会像这样:
for (var i = 0; i < locations.length; i++){
if (locations[i].address){
var googleRequestUrl = this.state.GoogleAPIUrl + locations[i].address;
const index = i;
fetch(googleRequestUrl)
.then((response) => response.json())
.then((responseJson) => {
locations[index].latitude = responseJson.results[0].geometry.location.lat;
locations[index].longitude = responseJson.results[0].geometry.location.lng;
})
.catch((error) => {
console.warn(error);
})
.done();
}
}
-
将循环变量传递给另一个获取数据并执行更改的函数
-
使用基本上执行 #2 但带有匿名函数的数组映射函数
```
locations.map((location) => {
if (location.address) {
var googleRequestUrl = this.state.GoogleAPIUrl + location.address;
fetch(googleRequestUrl)
.then((response) => response.json())
.then((responseJson) => {
location.latitude = responseJson.results[0].geometry.location.lat;
location.longitude = responseJson.results[0].geometry.location.lng;
})
.catch((error) => {
console.warn(error);
})
.done();
}
);