[英]Successive promise calls overriding return value
我有一个 React 站点,我设置了一个组件来显示当前温度以及 10 和 20 年前的当前温度。 (我正在使用DarkSky 。)
该组件看起来像这样(简化):
class WeatherPreview extends React.Component {
state = {
weather: {},
weatherTen: {},
weatherTwenty: {}
}
getWeather = async (years) => {
const targetDate = years ? moment().subtract(years, 'years') : null
const basePath = 'http://localhost:3000'
const res = targetDate ?
await fetch(`${basePath}/api/weather?date=${targetDate}`) :
await fetch(`${basePath}/api/weather`)
const weather = await res.json()
return weather
}
async componentDidMount() {
const weather = await this.getWeather()
const weatherTen = await this.getWeather(10)
const weatherTwenty = await this.getWeather(20)
this.setState({ weather, weatherTen, weatherTwenty })
}
render() {
const { weather, weatherTen, weatherTwenty } = this.state
return (
<div>
{weather.currently.temperature}°
{weatherTen.currently.temperatureTen}°
{weatherTwenty.currently.temperatureTwenty}°
</div>
)
}
}
API 端点代码如下所示(简化):
const darkskyOptions = {
latitude: 38.328732,
longitude: -85.764771,
language: 'en',
units: 'us',
exclude: ['minutely', 'hourly', 'daily', 'alerts', 'flags']
}
export default function handle(req, res) {
const date = req.query.date || null
if (!!date) {
darkskyOptions.time = date
}
else {
// Clear out time option if it's there
// Or else it will mess up our current weather call
delete darkskyOptions.time
}
const freshWeather = new Promise(resolve => resolve(
darksky.options(darkskyOptions).get()
))
freshWeather.then((newData) => {
res.json(newData)
}, (err) => {
console.log('Error retrieving Dark Sky weather data.')
console.log(err)
})
}
当我在代码更改后刷新页面时,第一次加载正确的数据:
90° 75° 72°
但是,当我在此初始加载后刷新页面时,过去 20 年的数据会替换当前数据。
72° 75° 72°
当我在 API 端点代码中记录内容时,从来没有任何东西会指示错误。 当前调用的time
属性永远不会存在,它似乎总是被删除,正确的选项似乎总是被传递。 从本质上讲,逻辑似乎已经过时了。
但是如果我在组件中记录weather
和weatherTwenty
,那么weather
肯定会保存weatherTwenty
的值。
我的代码模式有问题吗? 当那些 asnyc await 调用被发出时,它们是独一无二的,还是它们在返回时会“纵横交错”?
问题可能是因为您正在改变选项并在请求之间继续使用它。 尝试以下操作:
export default function handle(req, res) {
const date = req.query.date || null
//copy options and use that one
const copyOptions = {...darkskyOptions};
if (!!date) {
copyOptions.time = date
}
else {
// Clear out time option if it's there
// Or else it will mess up our current weather call
delete copyOptions.time
}
const freshWeather = new Promise(resolve => resolve(
darksky.options(copyOptions).get()
))
freshWeather.then((newData) => {
res.json(newData)
}, (err) => {
console.log('Error retrieving Dark Sky weather data.')
console.log(err)
})
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.