Angular 5+等待服务返回承诺

时间:2019-03-11 14:23:50

标签: angular promise observable wait

我有一个返回诺言的服务调用,但是当我尝试将返回类型设置为诺言时,由于无法识别类型,我在调用者函数中使用它遇到了麻烦。

所以我尝试使用下面的方法,但是遇到了计时问题(代码在调用完成之前执行)

  private getSomeData(): DataObjectArray[] {
    return this.myService.something().map((response: Response) => {
      return response.children;
    });
  }

  public compileData(): DifferentDataArray[] {

   // get some stuff from a config, then make service call
    let someData = this.getSomeData();

    /* If I have a promise returned, someData errors saying not an array type */
    for (let oneData of someData){
      /* loop through config data + service data making a return object array */
   }
    return this.dataCollection;
  }

3 个答案:

答案 0 :(得分:1)

我建议您在Angular中尝试使事物保持可观察的状态。保持一致很高兴,而不是在可观察对象和应许之间来回切换。

我不是很清楚myService.something()返回的是Promise还是Observable。如果可以观察到:

  private getSomeData(): Observable<<DataObjectArray[]> {
    return this.myService.something().pipe(
       map(response => response.children)
    );
  }

如果其承诺非常相似,但:

    private getSomeData(): Observable<<DataObjectArray[]> {
      return fromPromise(this.myService.something()).pipe(
       map(response => response.children)
      );
    }

然后:

  public compileData(): Observable<DifferentDataArray[]> {

   // get some stuff from a config, then make service call
    return this.getSomeData().pipe(
       map(someData => {
           /* If I have a promise returned, someData errors saying not an array type */
           var dataCollection = [];
           for (let oneData of someData){
            /* loop through config data + service data making a return object array */
                 // should dataCollection.push(changedData);
            }
            return dataCollection;
       });
    );

  }

最后在其他地方消费:

     this.compileData().subscribe(compiledData => {
         // do something with the compiled data
     });

注意: 管道运算符非常强大。它是可观察的,并且让您在返回之前对其进行一些处理。在这种情况下,我使用了地图运算符,因为您只是稍微改变了返回的形状。在链的末尾,您必须始终订阅一个可观察对象,以取回数据(在本示例中,最后一个黑色为准)

答案 1 :(得分:0)

  private getSomeData(): DataObjectArray[] {
    return this.myService.something().map((response: Response) => {
      return response.children;
    });
  }

应该是

  private getSomeData(): Promise<DataObjectArray[]> {
    return this.myService.something().map((response: Response) => {
      return response.children;
    });
  }

答案 2 :(得分:0)

您可以使用新的Javascript关键字asyncawait

首先使getSomeData异步,这也要求它返回承诺:

  private async getSomeData(): Promise<DataObjectArray[]> {
    return this.myService.something().map((response: Response) => {
      return response.children;
    });
  }

然后等待compileData中的函数:

let someData = await this.getSomeData();

但是,这意味着compileData也必须异步,因为它返回结果。这意味着您需要添加async关键字并将类型更改为Promise<DifferentDataArray[]>

万一您不关心结果,可以不等待就调用异步函数,因此您也不必等待结果,它会在后台处理。如果您依靠结果,则必须等待它。在这种情况下,您的应用程序的其他部分可以继续!无论如何,如果您正在设计异步应用程序,则必须考虑无论如何都会发生什么。

您完整的compileData函数:

 public async compileData(): Promise<DifferentDataArray[]> {

   // get some stuff from a config, then make service call
    let someData = await this.getSomeData();

    /* If I have a promise returned, someData errors saying not an array type */
    for (let oneData of someData){
      /* loop through config data + service data making a return object array */
   }
    return this.dataCollection;
  }


  public compileData(): DifferentDataArray[] {

   // get some stuff from a config, then make service call
    let someData = this.getSomeData();

    /* If I have a promise returned, someData errors saying not an array type */
    for (let oneData of someData){
      /* loop through config data + service data making a return object array */
   }
    return this.dataCollection;
  }