连续的承诺调用覆盖返回值



我有一个 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登录并在组件中weatherTwentyweather肯定持有weatherTwenty的值。

我的代码模式有问题吗?当那些等待电话时,他们是独一无二的还是可以在返回中"纵横交错"?

问题可能是因为您正在更改选项并在请求之间继续使用它。请尝试以下操作:

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)
})
}

最新更新