等待函数结束以使用 Underscore JS 和 React Native 设置状态
Wait for the end of a function to set state with UnderscoreJS under React Native
我想获取然后更新 markers 状态。问题是在我的获取结束之前状态正在更新(我认为是由于异步)。我认为 UnderscoreJS 使用 _.after 函数在我的获取结束后设置状态会有一个解决方案。我不知道该怎么做。有什么想法吗?
这是我的代码:
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);
}
你混合了同步和异步的想法,但它们混合得不好。
您最好将同步值转换为承诺(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);
}
接下来在事件处理程序中我 map 并将它们转换为 null
(在距离为 >= 1
的情况下)或从服务器获取新站数据 (fetch()
)。
这会产生一个由 promise 或 null 组成的数组。我使用 Underscore 的 .compact()
来删除空值(与过滤器相同)。然后我有一个传递给 Promise.all
的承诺数组,等待数组中的所有承诺都解决。当他们这样做时,它会将这些承诺的结果(作为数组)传递给 .then()
函数,我尽职尽责地使用 this.setState()
on.
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
是事件处理程序,因此它不会 return 承诺。相反,我们通过在 .catch()
块中记录它们来处理可能的错误。
参考资料
- Chaining in Underscore.js (miniarray.com)
- Promise - JavaScript | MDN (developer.mozilla.org)
- You're Missing the Point of Promises (blog.domenic.me)
我想获取然后更新 markers 状态。问题是在我的获取结束之前状态正在更新(我认为是由于异步)。我认为 UnderscoreJS 使用 _.after 函数在我的获取结束后设置状态会有一个解决方案。我不知道该怎么做。有什么想法吗?
这是我的代码:
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);
}
你混合了同步和异步的想法,但它们混合得不好。
您最好将同步值转换为承诺(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);
}
接下来在事件处理程序中我 map 并将它们转换为 null
(在距离为 >= 1
的情况下)或从服务器获取新站数据 (fetch()
)。
这会产生一个由 promise 或 null 组成的数组。我使用 Underscore 的 .compact()
来删除空值(与过滤器相同)。然后我有一个传递给 Promise.all
的承诺数组,等待数组中的所有承诺都解决。当他们这样做时,它会将这些承诺的结果(作为数组)传递给 .then()
函数,我尽职尽责地使用 this.setState()
on.
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
是事件处理程序,因此它不会 return 承诺。相反,我们通过在 .catch()
块中记录它们来处理可能的错误。
参考资料
- Chaining in Underscore.js (miniarray.com)
- Promise - JavaScript | MDN (developer.mozilla.org)
- You're Missing the Point of Promises (blog.domenic.me)