代码执行流程

时间:2017-04-06 11:37:53

标签: javascript angular

我来自Java背景。我开始学习Angular2,并且正在研究它。在我的一个项目中,我遇到了一个我无法理解的情况。

对于我的分页实现,我使用Angular2 observables获取数据库中所有可用招标的数量。获取值后,我只是将其登录到控制台,以确保代码正常工作。但它打印未定义。

这是我的代码的相关部分。

this.getNumberOfAllTenders();
console.log("number of tenders = "+this._numberOfAllTenders);

这是输出

  

投标数=未定义

以下是从后端获取投标数的方法

 getNumberOfAllTenders(){
         this._tendersService.getNumberOfAllTenders().
            subscribe(

            numberOfAllTenders => this._numberOfAllTenders = numberOfAllTenders,
            error => this._error_all_numbers = error

            );
            console.log('+++++++++++++++++++ number of tenders in db = '+this._numberOfAllTenders);
    }

在上面的代码片段中,还有一行要打印到控制台。它的输出也是未定义的。但是,一旦为变量分配了从后端获得的值,就会执行该行。

我确信,我的服务代码从后端获取值。我尝试在我的模板上打印它。它打印正确的值。

现在我的问题是,为什么要打印' undefined'在控制台中。这些变量正确分配值。据我所知,一旦调用了赋值给变量的函数,这些值就应该可用于代码的后半部分。

请在此澄清我。 Angular2中的代码执行流程是不同的?

1 个答案:

答案 0 :(得分:3)

它打印undefined因为observable运行异步,因此在console命令运行时它们没有完成运行。如果要对observable的返回值使用console.log,可以将console命令移到subscribe函数内:

this._tendersService.getNumberOfAllTenders().
            subscribe(
              numberOfAllTenders => {
                 this._numberOfAllTenders = numberOfAllTenders;
                 console.log('+++++++++++++++++++ number of tenders in db = '+this._numberOfAllTenders);
              },
              error => this._error_all_numbers = error
            );

在组件中使用从observable获取值的变量时,可以使用默认值,或者在必要时使用*ngIf进行空检查:

*ngIf="_numberOfAllTenders"

您还可以使用以下语法直接订阅可观察对象:

//in component
this._numberOfAllTenders = this._tendersService.getNumberOfAllTenders();

//in template
{{_numberOfAllTenders | async}}

这种方式this._numberOfAllTenders的类型为Observable<number>。您的模板可以使用async管道订阅它,该管道在后台调用subscribe并检索值。

从Angular 4开始,您可以在async语句中使用*ngIf并将值分配给本地模板变量:

<div *ngIf="_numberOfAllTenders | async; let myValue">{{myValue}}</div>

主要的是observable不会同步返回值,因此您需要调整其他代码才能使用它。因此,如果您需要使用一个observable中的值来调用第二个observable,您需要查看将{obonables与flatMap或类似的东西链接在一起:

firstObservable()
  .flatmap(dataFromFirst => secondObservable(dataFromFirst)
  .subscribe(dataFromSecond => //do something

或者如果你需要在继续第二个之前保存第一个observable的值:

firstObservable()
  .flatmap(dataFromFirst => {
      this.variable = dataFromFirst;
      return secondObservable(dataFromFirst)
   })
  .subscribe(dataFromSecond => //do something

希望这有帮助。