Последовательное обещание вызывает переопределение возвращаемого значения - PullRequest
0 голосов
/ 28 сентября 2019

У меня есть сайт 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 сделаны, они уникальны или могут быть «перекрещены» в своих возвращениях?

1 Ответ

0 голосов
/ 28 сентября 2019

Возможно, проблема вызвана тем, что вы изменяете параметры и продолжаете использовать их между запросами.Попробуйте следующее:

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