我想进行提取,然后更新标记状态。问题是在我的提取结束之前状态正在更新(由于异步,我认为)。我认为UnderscoreJS会使用_.after函数在我的fetch结束后设置状态。我不知道该怎么做。有什么想法吗?
这是我的代码:
onRegionChange(region) {
let latitude = region.latitude;
let longitude = region.longitude;
let markers = [];
_.filter(this.props.stations, (v) =>
{
if (this.getDistanceFromLatLonInKm(latitude,longitude,v.position.lat,v.position.lng) < 1) {
fetch('https://api.jcdecaux.com/vls/v1/stations/' + v.number + '?contract=Paris&apiKey=3a9169028401f05f02bcffd87f4a3963dcd52f63')
.then((response) => response.json())
.then((station) => {
console.log("station", station);
markers.push({
number: station.number,
coordinate: {
latitude: station.position.lat,
longitude: station.position.lng
},
title: station.name,
description: station.address,
banking: station.banking,
bonus: station.bonus,
status: station.status,
bike_stands: station.bike_stands,
available_bike_stands: station.available_bike_stands,
available_bikes: station.available_bikes,
last_update: station.last_update
});
})
.catch((error) => {
console.warn(error);
});
}
}
)
this.setState({
markers: markers
})
console.log("markers", this.state.markers);
}
答案 0 :(得分:0)
混合同步和异步的想法,它们混合不好。
最好将同步值转换为promises(fetch
正在做的事情)。
首先,我将传动部件分解为功能。这样可以清理实际代码并降低复杂性。
function stationFetchUrl(station) {
return `https://api.jcdecaux.com/vls/v1/stations/${station.number}?contract=Paris&apiKey=3a9169028401f05f02bcffd87f4a3963dcd52f63`;
}
function convertStationData(station) {
return {
number: station.number,
coordinate: {
latitude: station.position.lat,
longitude: station.position.lng
},
title: station.name,
description: station.address,
banking: station.banking,
bonus: station.bonus,
status: station.status,
bike_stands: station.bike_stands,
available_bike_stands: station.available_bike_stands,
available_bikes: station.available_bikes,
last_update: station.last_update
};
}
function stationNearRegion(region, station) {
const distance = this.getDistanceFromLatLonInKm(
region.latitude,
region.longitude,
stationStub.position.lat,
stationStub.position.lng
);
return (distance < 1);
}
接下来在事件处理程序中我映射在工作站上并将它们转换为null
(在距离为>= 1
的情况下)或获取新工作站数据来自服务器(fetch()
)。
这会产生一个promises或null数组。我使用Underscore的.compact()
来删除null(与过滤器相同)。然后我有一个承诺数组,我传递给Promise.all
,等待数组中的所有承诺解析。当他们这样做时,它将这些承诺的结果(作为数组)传递给.then()
函数,我尽职尽责地使用this.setState()
。
onRegionChange(region) {
const markerPromises = _.chain(this.props.stations)
.map(stationStub => {
if (stationNearRegion.call(this, region, stationStub) {
return fetch(stationFetchUrl(station))
.then(response => response.json())
.then(convertStationData);
}
})
.compact()
.value();
Promise.all(markerPromises)
.then(markers => this.setState({markers}))
.catch(error => console.log(error.toString()));
});
由于onRegionChange
是一个事件处理程序,因此它不会返回一个promise。相反,我们通过在.catch()
块中记录它们来处理可能的错误。