简体   繁体   English

连续 promise 调用覆盖返回值

[英]Successive promise calls overriding return value

I have a React site and I've set up a component to display the current temperature as well as the current temperature 10 and 20 years ago.我有一个 React 站点,我设置了一个组件来显示当前温度以及 10 和 20 年前的当前温度。 (I'm using DarkSky .) (我正在使用DarkSky 。)

The component looks like this (simplified):该组件看起来像这样(简化):

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

The API endpoint code looks like this (simplified): 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)
  })
}

When I refresh the page after a code change the correct data loads the first time:当我在代码更改后刷新页面时,第一次加载正确的数据:

90° 75° 72°

However, when I refresh the page after this initial load, the data for 20 years in the past replaces the current data.但是,当我在此初始加载后刷新页面时,过去 20 年的数据会替换当前数据。

72° 75° 72°

When I log things in the API endpoint code there is never anything that would indicate an error.当我在 API 端点代码中记录内容时,从来没有任何东西会指示错误。 The time property is never there for the current call, it always seems to be deleted, the correct options always seemed to be passed.当前调用的time属性永远不会存在,它似乎总是被删除,正确的选项似乎总是被传递。 Essentially the logic seems to check out.从本质上讲,逻辑似乎已经过时了。

But if I log weather and weatherTwenty in the component, weather is definitely holding the value of weatherTwenty .但是如果我在组件中记录weatherweatherTwenty ,那么weather肯定会保存weatherTwenty的值。

Is there something wrong with my code pattern?我的代码模式有问题吗? When those asnyc await calls are made are they unique or can they get "crisscrossed" in their returns?当那些 asnyc await 调用被发出时,它们是独一无二的,还是它们在返回时会“纵横交错”?

Problem is probably caused because you're mutating options and keep using it between requests.问题可能是因为您正在改变选项并在请求之间继续使用它。 Try the following:尝试以下操作:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM