【问题标题】:Why can't I access api fetch response?为什么我无法访问 api 获取响应?
【发布时间】:2021-05-04 13:31:32
【问题描述】:

我是异步进程的新手,我不明白为什么我当前尝试存储从 fetch 请求到 api 的响应的方法不起作用。

我正在构建 Angular 应用程序,其中有一个 api.service.ts 文件,我在其中定义了我的获取函数。当我在组件中使用这些函数并尝试使用响应设置变量时,在函数调用中我可以访问响应,但在外部它就像我从未设置变量值一样。

我的 api.service.ts 文件目前:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  API_Key = 'cf002751564a4c78f5f7ed479f1b9ba3';

public getWeatherCity(city_name) {
    return new Promise((resolve, reject) => {
      fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city_name}&appid=${this.API_Key}`)
        .then(response => {
          return response.json();
        }).then(data_fetched => {
          let data = data_fetched.results;
          resolve(data);
        })
    })
};

constructor(private http: HttpClient) { }
}

不过我也试过

public getWeatherCity(city_name) {
return this.http.get(`https://api.openweathermap.org/data/2.5/weather?q=${city_name}&appid=${this.API_Key}`);
}

我尝试在其中使用 api.service 的 component.ts:


import { Component, OnInit } from '@angular/core';
import { ApiService } from '../../api.service';
import { SearchComponent } from '../search.component';
import { FormBuilder } from '@angular/forms';



@Component({
  selector: 'app-city',
  templateUrl: './city.component.html',
  styleUrls: ['./city.component.css']
})
export class CityComponent implements OnInit {
  cityName;
  displayResults = false;
  weather;
  weatherLocation;

  constructor(private apiService: ApiService) { }

  ngOnInit(): void {
    this.cityName = "Cleveland";
    this.apiService.getWeatherCity(this.cityName).then(data => {
      this.weather = data
      this.weatherLocation = data['name'];
      console.log(this.weather);
    })
    console.log(this.weather);
    console.log(this.weatherLocation);
  }

 
}

我希望得到第一个和第二个 console.log(this.weather) 的结果,但是我得到了第一个的结果(在 fetch 函数内),但第二个返回 undefined(在 fetch 函数之外)。我不确定我对这里的异步函数有什么不了解。当然必须有一种方法来存储响应,以便可以在函数之外访问它。

我确实意识到我可以在 getWeatherCity 函数中修改我的 html,但这似乎是一个混乱且不可取的解决方案。

任何帮助将不胜感激。

【问题讨论】:

    标签: angular api fetch-api asynchronous-javascript


    【解决方案1】:

    如果您要使用http.get,那么您需要订阅该流,因为http.get 返回一个Observable

      public getWeatherCity(city_name) {
        return this.http.get(
          `https://api.openweathermap.org/data/2.5/weather?q=${city_name}&appid=${
            this.API_Key
          }`
        );
      }
    

    // ....

      ngOnInit(): void {
        this.cityName = "Cleveland";
        this.subscription = this.apiService
          .getWeatherCity(this.cityName)
          .subscribe(data => {
            this.weather = data;
            this.weatherLocation = data["name"];
            console.log(this.weather);
            console.log(this.weatherLocation);
          });
      }
    
      ngOnDestroy() {
        this.subscription.unsubscribe();
      }
    

    https://stackblitz.com/edit/angular-ivy-bzcnj2?file=src%2Fapp%2Fapp.component.ts

    【讨论】:

    • 这仍然为第二个和第三个 console.log 的返回 undefined。
    • 我更新了答案,控制台日志应该在订阅内,因为流的异步性质
    • 一开始没注意console.logs
    • 那么我有什么办法可以在函数之外更改 HTML 或变量?我目前有这个工作,但看起来非常笨重:this.apiService.getWeatherCity(this.cityName) .subscribe(data => { const weather = this.apiService.weatherReport(data) const div = document.getElementById("weather"); div.innerHTML = ` <ul> <li> ${weather['location']} </li> <li> ${weather['fahrenheit']} *F </li> </ul> ` } )
    【解决方案2】:

    您的第二个和第三个 console.logs 发生在您的 apiService.getWeatherCity() 返回之前。它是异步的,因此不会阻塞执行。服务请求被触发,并立即命中下一行。接下来。在某个时刻,服务调用返回,您的 .then() 方法运行。

    【讨论】:

      猜你喜欢
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-18
      • 1970-01-01
      • 2013-02-09
      • 1970-01-01
      • 2014-04-16
      相关资源
      最近更新 更多