如何将值从函数传递给函数?

时间:2017-08-07 14:01:07

标签: javascript typescript

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

以前使用承诺的工作。有很多头痛。是否有更简单的方法来获取数据?

感谢任何帮助和建议。在此先感谢:)

map.ts

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

    });

}

1 个答案:

答案 0 :(得分:3)

您可以在此处创建包含纬度和经度的可观察流,并在计算功能中订阅该流。这意味着您永远不会在业务逻辑中调用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方法设为不纯函数,则无法从load方法之外调用calculate。我建议不要试图保持服务中userLatuserLon属性的状态,因为随着复杂性的增加,这很难调试。

然而,你走了:

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