如何在subscribe Angular 4中返回值

时间:2018-04-02 03:54:01

标签: angular typescript rxjs observable

我是棱角分明的观察者。我有一个问题想要在subscribe方法中返回一个值。我有 以下方法(getFirebaseData(idForm:string):observable <any[]>):

getTotalQuestions(idForm:string){
let totalQuestions:number;
this.getFirebaseData(idForm+"/Metadatos")
.subscribe(items => 
  {
    items.map(item => {
      totalQuestions=item.Total;
      console.log(totalQuestions);
    });
  }
);
console.log(totalQuestions);
return totalQuestions;
}

第一次console.log(totalQuestions)打印 4 ,但第二次console.log(totalQuestions)打印未定义。 我理解subscribe是一个异步操作,因此第二个console.log(totalQuestions)(“为了编写代码”)打印未定义,但我找不到在subscribe方法之后返回变量的方法完成。现在,如果我更改订阅地图:

getTotalQuestions(idForm:string){
let totalQuestions:number;
this.getFirebaseData(idForm+"/Metadatos")
.subscribe(items => 
  {
    items.map(item => {
      totalQuestions=item.Total;
      console.log(totalQuestions);
    });
  }
);
console.log(totalQuestions);
return totalQuestions;
}

第一个console.log(totalQuestions)不打印任何内容,第二个console.log(totalQuestions)打印未定义。这是我不理解的事情,因为它发生了。

我希望你能帮助我澄清我不理解的概念。谢谢!

4 个答案:

答案 0 :(得分:9)

您无法直接返回 totalQuestions ,您需要使用主题来实现这一目标。

getTotalQuestions(idForm:string): Observable<string> {
let totalQuestions:number;
var subject = new Subject<string>();
this.getFirebaseData(idForm+"/Metadatos")
.subscribe(items => {
    items.map(item => {

      totalQuestions=item.Total;
      console.log(totalQuestions);
      subject.next(totalQuestions);
    });
  }
);
  return subject.asObservable();
}

用法:getTotalQuestion(idForm).subscribe((r)=>console.log(r))

答案 1 :(得分:2)

当您订阅它时,Observable运行以及从订阅返回的内容始终是setInterval之类的订阅对象。第一个样本:因为这是一个异步调用,第二个console.log不会等到子目录完成它才能执行。

getTotalQuestions(idForm:string){
let totalQuestions:number;
this.getFirebaseData(idForm+"/Metadatos")
 .map(items => 
     items.map(item => {
     totalQuestions=item.Total;
     console.log(totalQuestions);
  });
)
}
getTotalQuestion('231').subscribe(console.log)

答案 2 :(得分:0)

I made a live example。 您不需要触发订阅以对数组进行转换或将某些对象减少为单个值,这是我的接近。 您的服务

getTotalQuestions(idForm: string): Observable<any> {
    return this.getFirebaseData(`${idForm}/Metadatos`)
        .pipe(map(items => items
            .map(item => item.Total)
            .reduce((a, b) => a+b), 0));
}

您的组件

this.service.getTotalQuestions('id')
    .subscribe(totalQuestions => console.log(totalQuestions));

答案 3 :(得分:0)

为解决这个问题,我将创建一个totalQuestions$可观察的属性

在TS文件中

totalQuestions$ = this.getFirebaseData(idForm + "/Metadatos").pipe(
  map(items => items.reduce((prev, {Total}) => prev + Total), 0)))
)

现在,您可以在模板中使用async管道

<span>{{ totalQuestions$ | async }}</span>

如果您想在TS文件中使用该变量,则可以使用forkJoin之类的组合运算符或CombineLatest来访问该值

newVariable$ = combineLatest([totalQuestions$, ...]).pipe(
  map(([totalQuestions, ... ]) => {
    // Perform an operation here and return a value
  })
)