Состояние гонки при вызове компонентов - PullRequest
0 голосов
/ 23 марта 2020

У меня есть 2 компонента, которые загружаются в «приложение», первый компонент разрешает внешний IP-адрес для гео, делая 2 ax ios .get вызова, а затем возвращает их (через emit) в приложение. vue.

Затем я вызываю «Погода», чтобы разрешить широту / долготу из предыдущих 2 вызовов на некоторый json, возвращенный darksky API для этой широты / долготы. Иногда (в 50-60% случаев) я сталкиваюсь с состоянием гонки, когда отправляю 0/0 в погоду (это то, к чему я инициализирую широту / долготу в приложении. vue) и не знаю, как решить Это. Я хотел бы, чтобы следующий код работал более надежно.

Приложение. vue

image

ip_resolve. vue

<template>
  <div class="Hemlo">

  </div>
</template>

<script>
const axios = require('axios').default;
const ipRegex = /ip=(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})$/gmi
export default {
  name: 'ip',
  props:{
      ip: String,
      country: String,
      City: String,
      lat: Number,
      long: Number
  },
  mounted () {
    axios.get('https://www.cloudflare.com/cdn-cgi/trace')
    .then(response => (
        this.ip = ipRegex.exec(response.data)[1]
    )
        .then(
            axios.get('https://cors-anywhere.herokuapp.com/http://api.ipstack.com/'+this.ip+'?access_key=<key>')
            .then( response => (
                    this.lat = response.data.latitude,
                    this.long = response.data.longitude,
                    this.country = response.data.country_name,
                    this.city = response.data.city
                ).then(
                    this.$emit('response', {
                        ip: this.ip,
                        lat: this.lat,
                        long: this.long,
                        country: this.country,
                        city: this.city
                    })
                )
            )
        )
    )
  }
}
</script>

Погода. vue

<template>
  <div class="Hi">
    <h1>{{msg}} {{city}}, {{country}}</h1>
    <h2>Temp: {{ temp }}f</h2>
    <h2>Conditions: {{ conditions }}</h2>
  </div>
</template>

<script>

const axios = require('axios').default;
export default {
  name: 'Weather',
  props: {
    msg: String,
    resp: String,
    ip: String,
    lat: Number,
    long: Number,
    city: String,
    country: String,
    temp: String,
    conditions: String
  },
  mounted () {
    axios
      .get('https://cors-anywhere.herokuapp.com/https://api.darksky.net/forecast/<key>/'+this.lat+','+this.long)
      .then(response => (
        this.resp = response.data,
        this.temp = response.data.currently.temperature,
        this.conditions = response.data.currently.summary
      ))
  }

}
</script>

1 Ответ

1 голос
/ 23 марта 2020

Как правило, вы должны разделить эту модель logi c на ее собственный модуль, используя что-то вроде vuex, поэтому поток данных для компонентов является полностью однонаправленным.

Но в этом случае самое простое решение заключается в добавлении директивы v-if="responseReady" к компоненту <Weather> в приложении. vue, чтобы он не монтировался до тех пор, пока данные не будут готовы. Вам также нужно будет добавить логический флаг для этой новой реквизита в data и onResponse. Опять же, это быстрое и грязное решение.

  <Weather v-if="responseReady"  msg="The weather for:" :lat="lat" :long="long" :ip="ip" :city="city" :country="country"/>
...
  data() {
    return {
        lat: 0,
        long: 0,
        ip: 0,
        country: 0,
        city: 0,
        responseReady: false
      }
    }, 
...
    onResponse(event) {
      this.lat = event.lat
      this.long = event.long
      this.ip = event.ip
      this.country = event.country
      this.city = event.city
      this.responseReady = true;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...