Порядок выполнения углового метода обслуживания - PullRequest
0 голосов
/ 20 мая 2019

Я новичок в Angular и сейчас пытаюсь выучить его и у меня возникла проблема.У меня есть простой метод обслуживания, который я вызываю в другом компоненте.Но у меня странный порядок выполнения:

enter image description here

Вы можете увидеть это в браузере консоли:

enter image description here

Может кто-нибудь объяснить, как это работает?И как это исправить?

Ответы [ 3 ]

1 голос
/ 20 мая 2019

Это связано с тем, что операции ввода-вывода обычно предназначены для неблокирования. Настройка запроса через http.get является такой неблокирующей операцией. На завершение требуется время, и в то же время ваш другой код будет выполняться первым.

Вы бы не хотели, чтобы ваше приложение зависало, пока оно ожидает 5-секундного ответа от сервера, не так ли?

Если вы хотите отобразить свой результат, вы можете просто разделить свою логику для этого, например, так:

_weatherForecast: WeatherForecast = null;

calculateWeatherForecast() {
  this.http.get<WeatherForecast>(this._url).subscribe((data) => {
      this._weatherForecast = data;
  });
}

getWeatherForecast() {
    return this._weatherForecast;
}

Таким образом, вы можете получать свои данные независимо от их отображения. Angular обнаружит изменение вашей переменной и выдаст результат. В вашем шаблоне вы просто сделаете:

<div>{{getWeatherForecast()}}</div>

Преимущество этого заключается в том, что вы не будете получать новые данные с сервера каждый раз, когда хотите отобразить weatherForecast. Это дает вам больше контроля над тем, как часто и когда запрашивать у вашего сервера новые данные.

Edit:

Как было указано в комментариях, код будет нарушен при попытке доступа к свойству (в данном случае summary) на _weatherForecast. Если вы хотите избежать этого, у вас есть два варианта:

  1. Измените ваш шаблон на:
<div>{{ getWeatherForecast()?.summary }}</div>
  1. Измените логику в вашем компоненте на:
getWeatherForecast() {
    if(this._weatherForecast) {
        return this._weatherForecast.summary;
    }
}

Вы также можете изменить метод getWeatherForecast() на get weatherForecast(). Таким образом, вы можете получить к нему доступ в своем шаблоне как свойство вашего компонента, например:

<div>{{ weatherForecast?.summary }}</div>

Надеюсь, это поможет!

1 голос
/ 20 мая 2019

В вашем коде 2 части:

Синхронный

Часть за пределами вашего метода подписки является синхронной, то есть она будет выполняться сразу после выполнения вашей программы.

Асинхронный

Часть внутри вашего метода подписки является асинхронной, т.е. она будет выполняться только после завершения запроса get (ответ будет возвращен).

Объяснение

Теперь, поскольку запрос http на сервер займет некоторое время. поэтому часть synchrouns продолжит свое выполнение и не будет ждать завершения запроса get. поэтому console.log [1] будет выполняться первым.

Линия

return this.weatherForcast

выполняется следующим образом из-за синхронного кода и возвращает undefined, что вызывает ошибку в консоли [2]

Ваша функция subscribe затем вызывается в какой-то момент позже (когда запрос get завершен), и данные отображаются в консоли [3].

Надеюсь, это поможет :) Дайте мне знать, если вам нужно больше объяснений :)

1 голос
/ 20 мая 2019

Код вне метода subscribe () всегда выполняется последним. Неважно, будет ли он до или после, если он на том же уровне.

Чтобы исправить это, вместо использования метода "get", используйте глобальную переменную и инициализируйте ее в ngOnInit ().

weather :WeatherForecast = null;

ngOnInit(){
  this.http.get<WeatherForecast>(this._url).subscribe(
    data => {
       this.weather = data;
    }
  )
}

Я предлагаю вам организовать http-вызовы между component.ts и сервисом, чтобы сделать его более независимым.

Надеюсь, это поможет вам:)

...