我是棱角分明的观察者。我有一个问题想要在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)
打印未定义。这是我不理解的事情,因为它发生了。
我希望你能帮助我澄清我不理解的概念。谢谢!
答案 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
})
)