【问题标题】:Service returning data but can't subscribe服务返回数据但无法订阅
【发布时间】:2019-10-30 16:19:31
【问题描述】:

在我的 component.ts 中,我从我的服务类中调用一个函数,该函数从我的后端 rest api 中检索数据。记录结果时,我成功检索了数据,但尝试在我的组件中订阅它时没有任何反应

vehicles: VehicleDto[] = [];

  constructor(private myService: MyService) {

    console.log(this.myService.getVehicles());
    console.log("Before Service call");
    this.myService.getVehicles().subscribe((result: any[]) => {

      console.log("service called");
      this.vehicles = result;
      console.log(this.vehicles); //this is console for vehicles     
    });
    console.log("after service call");
  }

在我的服务类中:

 getVehicles() : Observable<VehicleDto[]> {

    let resultSubject: AsyncSubject<VehicleDto[]> = new AsyncSubject();
    let httpOptions = this.kecloakService.buildHeaderWithToken();
    this.configurationService.loadNetworkConfiguration(false).subscribe((config: NetworkConfiguration) => {

      if (config) {
        this.http.get(config.getHostUrl + this.url + "getVehicles", httpOptions)
        .subscribe((entities: VehicleDto[]) => {
          let results: VehicleDto[] = [];
          for(let entity of entities) {
            results.push(entity);
          }
          resultSubject.next(results);
          resultSubject.complete;
        });
      }
    });
    return resultSubject;
  }

这是我在控制台中得到的结果

如您所见,我确实取回了数组,但在订阅中,结果永远不会被记录或分配给车辆。

【问题讨论】:

  • 改用promise。
  • @MalavanRockzz 为什么使用 promise 而不是 Observable ? medium.com/javascript-everyday/…
  • 你也返回 AsyncSubject 但你的签名说:Observable
  • 首先他应该摆脱他的嵌套订阅。
  • @Yvan 我相信 Malavan Rockzz 说 Promises 时的意思是异步等待

标签: angular


【解决方案1】:

这是因为异步特性。请告知自己有关回调的信息。当您难以理解回调时,请随意使用 async-await。 摆脱您的嵌套订阅!

// Variant A+B
vehicles: VehicleDto[];
// Veriant C
vehicles$: Observable<VehicleDto[]>;

constructor(private myService: MyService) {
    // Variant A: async-await
    this.vehicles = await this.myService.getVehiclesPromised();

    // Variant B: callback (least recommended, do not forget to unsubscribe!)
    // this.myService.getVehicles().subscribe((result: VehicleDto[]) => {
    // this.vehicles = result;
    // });

    // Variant C: Observable (use async pipe in template to access data)
    //this.vehicles$ = this.myService.getVehicles();
}

async getVehiclesPromised(): Promise<VehicleDto[]> {
    const httpOptions = this.kecloakService.buildHeaderWithToken();

    const config: NetworkConfiguration = await this.configurationService.loadNetworkConfigurationPromised(false);
    return config ? await this.http.get(config.getHostUrl + this.url + "getVehicles", httpOptions).toPromise() : [];
}

【讨论】:

    【解决方案2】:

    你可以创建一个 Observable 并且应该可以工作:

      getVehicles(): Observable<VehicleDto[]> {
        let httpOptions = this.kecloakService.buildHeaderWithToken();
        return new Observable((obs => {
          this.configurationService.loadNetworkConfiguration(false).subscribe((config: NetworkConfiguration) => {
            if (config) {
              this.http.get(config.getHostUrl + this.url + "getVehicles", httpOptions)
                .subscribe(
                  (entities: VehicleDto[]) => {
                    let results: VehicleDto[] = [];
                    for (let entity of entities) {
                      results.push(entity);
                    }
                    obs.next(results);
                    obs.complete();
                  }
                );
            }
          });
        }));
      }
    

    【讨论】:

      【解决方案3】:

      你可以把最后一行改成:

      return resultSubject.asObservable();
      

      并且服务将返回类型为Observable&lt;VehicleDto[]&gt; 的对象,您当前返回的类型为AsyncSubject

      【讨论】:

        猜你喜欢
        • 2019-05-27
        • 2020-06-23
        • 1970-01-01
        • 2021-08-06
        • 2022-12-06
        • 2021-12-05
        • 2020-01-03
        • 2021-05-21
        • 1970-01-01
        相关资源
        最近更新 更多