【问题标题】:How to wait for a function to return data from the observable response?如何等待函数从可观察响应中返回数据?
【发布时间】:2019-08-20 16:50:46
【问题描述】:

在我的 home.ts 中,我正在调用服务中的一个函数,该函数使用来自 firestore 响应(可观察)的数据填充数组,但是当我尝试从 home.ts 访问这些数据时未定义,因为它没有等待为要完成的功能。我尝试使用 await async 等待,但仍然无法正常工作。

这是我的代码:

home.ts

async addMarkers(){
    console.log("before await");
    let dataMarkers:MarkerOptions[] = await this.wcService.getWcData();
    console.log("after de await"); //executed before getWcData response
    console.log(dataMarkers); //Here is undefined
    ...`

wcService.ts

async getWcData() {
    let wcsCollection = this.db.collection<Wc>('wcs');
    wcsCollection.valueChanges().subscribe(res=>{
      res.forEach(element => {   
          this.addWcToMarkerOptionsArray(element.latitude,element.longitude,element);
          console.log("added element to this.markersWc");
      });
      console.log("returning results: " + this.markersWc);
      return this.markersWc;
    });
}

控制台日志按以下顺序显示: "Before await" "After await" "returning results...."

如何强制函数等待结果?

非常感谢!

【问题讨论】:

    标签: angular typescript firebase ionic-framework


    【解决方案1】:

    您可以使用toPromiseObservable 转换为Promise

    import 'rxjs/add/operator/toPromise'
    

    那么您的服务将是这样的:

    async getWcData() {
        let wcsCollection = this.db.collection<Wc>('wcs');
        const result = await wcsCollection.valueChanges().toPromise();
        result.forEach(element => { 
          this.addWcToMarkerOptionsArray(element.latitude,element.longitude,element);
          console.log("added element to this.markersWc");
        });
        return this.markersWc;
    }
    

    【讨论】:

    • 请注意,我返回的是我自己在 wcService (MarkerOptions) 中创建的对象。如果我使用 toPromise() 我收到以下错误: src/app/home/home.page.ts(138,72) 中的错误:错误 TS2339:Promise 类型上不存在属性“toPromise” '。
    • 我更新了答案,你可以查看
    • 感谢您的帮助,但仍然无法正常工作,我确定我错过了一些东西。正如你所说,我已经添加了 toPromise,但现在代码挂在 valueChanges 行上,永远不会更进一步。
    【解决方案2】:

    observable 必须在 promise 解决之前完成。
    您使用 'first' 运算符解决问题,该运算符采用第一个发出的值,然后完成组合的 observable:

    async getWcData() {
        let wcsCollection = this.db.collection<Wc>('wcs');
        const result = await wcsCollection.valueChanges().first().toPromise();
        result.forEach(element => { 
          this.addWcToMarkerOptionsArray(element.latitude,element.longitude,element);
          console.log("added element to this.markersWc");
        });
        return this.markersWc;
    }
    

    【讨论】:

      猜你喜欢
      • 2018-12-16
      • 2019-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多