我试图将从http请求获得的值推送到本地声明变量userLat & userLng,并从另一个函数访问变量,但得到undefined作为结果。 userLat & userLng已成功检索。使用return this.userLat & this.userLng尝试过,但失败了,如果我有任何错误,请指出。

以前使用承诺的方式工作。头疼得厉害。有没有更简单的方法来获取数据?

任何帮助和建议,表示赞赏。提前致谢:)

地图

export class GoogleMapsProvider {

userLat:any;
userLng:any;

constructor(
public http: Http,
) {
}

load(){
   this.http.post()
  .map(res => res.json())
  .subscribe(data =>
  {
      this.userDetails = data[0];

      this.userLat = this.userDetails.ListerLat;
      this.userLng = this.userDetails.ListerLng;

      console.log(this.userLat); // successfully return userLat
      console.log(this.userLng); // successfully return userLng

     //tried return this.userLat & this.userLng

  }
}


calculate(locations) {

  console.log(this.userLat); //returned undefined
  console.log(this.userLng); //returned undefined

  let usersLocation = {
  lat: this.userLat,
  lng: this.userLng
};

}


用诺言

    load(){

    if(this.data){
        return Promise.resolve(this.data);
    }

    return new Promise(resolve => {

        this.http.get('../example.json').map(res => res.json()).subscribe(data => {

this.data = data;

            resolve(this.data);
        });

    });

}

最佳答案

您可以在此处创建包含纬度和经度的可观察流,并在您的calculate函数中进行订阅。这意味着您永远不会在业务逻辑中调用calculate,只在实例化服务时才调用一次。

每当数据从load方法返回时,您的calculate逻辑都会被触发。您可以相信,当您从服务器获得响应时,这种情况将永远发生,并且您不必自己管理计算调用。

有几件事:


从您的服务中删除纬度/经度属性。
创建一个包含两个值(纬度/经度)的Observable流
立即订阅该流,因此,只要您的load函数将值添加到流中,就将进行计算。


您的服务如下所示:

import { ReplaySubject } from 'rxjs/ReplaySubject';

export interface Location {
    latitude: number;
    longitude: number;
}

export class GoogleMapsProvider {
    private locationStream: ReplaySubject<Location> = new ReplaySubject();

    constructor(public http: Http) {
        // Subscribes to the location observable stream.
        this.calculate();
    }

    load(){
        this.http.post()
            .map(res => res.json())
            .subscribe(data => {
                this.userDetails = data[0];

                // This will add the location values to the stream.
                this.locationStream.next({
                    latitude: this.userDetails.ListerLat,
                    longitude: this.userDetails.ListerLon
                });
            });
    }


    calculate() {
        // Any time the `load` adds values to the stream, the subscribe callback will be triggered.
        this.locationStream.asObservable().subscribe((location: Location) => {
            // Do some calculations using location.latitude and location.longitude
        });
    }
}


如果您不喜欢使用Observable流的方法,则仍可以通过使calculate函数纯净来实现此目的。

因此,您无需访问this.userLatthis.userLon,而是传递位置对象,从而使calculate函数完全脱离其输入-这样,如果您确保仅使用calculate调用calculate,就不会有未定义的值。定义的值。

但是,这种方法的唯一问题是,如果不使load方法成为不纯函数,则无法从calculate方法外部调用userLat。而且我建议不要尝试使用服务中的userLon和属性保持状态,因为随着复杂性的增加,这可能很难调试。

不过,您可以在这里:

export interface Location {
    latitude: number;
    longitude: number;
}

export class GoogleMapsProvider {
    constructor(public http: Http) {}

    load() {
        this.http.post()
            .map(res => res.json())
            .subscribe(data => {
                this.userDetails = data[0];

                // Call `calculate` here and pass in location object.
                this.calculate({
                    latitude: this.userDetails.ListerLat,
                    longitude: this.userDetails.ListerLon
                });
            });
    }


    calculate(location: Location) {
        // Do calculations with location.latitude and location.longitude
    }
}

10-08 13:13