Angular 2 Firebase Observable 承诺不会 return 任何东西
Angular 2 Firebase Observable to promise doesn't return anything
我目前正在使用 AngularFire2 开发一个 Angular 2 项目,我正在尝试将 FirebaseListObservable 转换为 Promise。我知道这没有多大意义,因为 Observables 更有用,但这个函数将成为另一个函数的一部分,其中链接了多个承诺。而且我不熟悉如何在承诺链中订阅 Observables...该函数在服务中执行,但它似乎没有 return 任何东西。
基本上,我想做的是检查一个 Firebase 列表是否已经存在具有特定名称的对象并且 return 是真还是假。
服务
constructor(private _af: AngularFire) { }
nameExists(name: string): Promise<boolean> {
return this._af.database.list('users')
.map(users => {
let exists = false;
users.forEach(user => {
if(user.name.toLowerCase() === name.toLowerCase()) {
console.log('Name already exists!');
exists = true;
}
});
return exists;
}).toPromise();
}
组件
constructor(private _usersService: UsersService) { }
check(name) {
this._usersService.nameExists(name)
.then(bool => console.log(bool));
}
所以函数被执行,并且当它打印到控制台时似乎正常工作,当有匹配项时。但是,组件中的 console.log() 不会被执行。我想 "then" 部分永远不会到达。另外,有没有办法在找到匹配项后停止 forEach 循环?
任何帮助将不胜感激,因为我根本找不到任何答案。
问题在于 toPromise
运算符将 observable 转换为解析为 observable 最终值的承诺。这意味着可观察对象必须在承诺解决之前完成。
在 AngularFire2 中,列表和对象可观察对象不完整;他们 re-emit 每当数据库发生变化时。
您可以使用 first
运算符解决问题,该运算符获取第一个发出的值,然后完成组合的可观察对象:
import 'rxjs/add/operator/first';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
...
return this._af.database
.list('users')
.map(users => {
let exists = false;
users.forEach(user => {
if (user.name.toLowerCase() === name.toLowerCase()) {
console.log('Name already exists!');
exists = true;
}
});
return exists;
})
.first()
.toPromise();
我通过在收到第一个数据后以懒惰的方式取消订阅来解决这个问题:)
const userSubs$ = this.db.object(`branch/${branchId}/products`).subscribe(
async (payload: any) => {
userSubs$.unsubscribe();
})
或者将你的代码转换成类似这样的好方法:)
const eventref = this.db.database.ref(`branch/${branchId}/products`);
const snapshot = await eventref.once('value');
const productArray = snapshot.toJSON()
return productArray;
快乐编码
我目前正在使用 AngularFire2 开发一个 Angular 2 项目,我正在尝试将 FirebaseListObservable 转换为 Promise。我知道这没有多大意义,因为 Observables 更有用,但这个函数将成为另一个函数的一部分,其中链接了多个承诺。而且我不熟悉如何在承诺链中订阅 Observables...该函数在服务中执行,但它似乎没有 return 任何东西。 基本上,我想做的是检查一个 Firebase 列表是否已经存在具有特定名称的对象并且 return 是真还是假。
服务
constructor(private _af: AngularFire) { }
nameExists(name: string): Promise<boolean> {
return this._af.database.list('users')
.map(users => {
let exists = false;
users.forEach(user => {
if(user.name.toLowerCase() === name.toLowerCase()) {
console.log('Name already exists!');
exists = true;
}
});
return exists;
}).toPromise();
}
组件
constructor(private _usersService: UsersService) { }
check(name) {
this._usersService.nameExists(name)
.then(bool => console.log(bool));
}
所以函数被执行,并且当它打印到控制台时似乎正常工作,当有匹配项时。但是,组件中的 console.log() 不会被执行。我想 "then" 部分永远不会到达。另外,有没有办法在找到匹配项后停止 forEach 循环?
任何帮助将不胜感激,因为我根本找不到任何答案。
问题在于 toPromise
运算符将 observable 转换为解析为 observable 最终值的承诺。这意味着可观察对象必须在承诺解决之前完成。
在 AngularFire2 中,列表和对象可观察对象不完整;他们 re-emit 每当数据库发生变化时。
您可以使用 first
运算符解决问题,该运算符获取第一个发出的值,然后完成组合的可观察对象:
import 'rxjs/add/operator/first';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
...
return this._af.database
.list('users')
.map(users => {
let exists = false;
users.forEach(user => {
if (user.name.toLowerCase() === name.toLowerCase()) {
console.log('Name already exists!');
exists = true;
}
});
return exists;
})
.first()
.toPromise();
我通过在收到第一个数据后以懒惰的方式取消订阅来解决这个问题:)
const userSubs$ = this.db.object(`branch/${branchId}/products`).subscribe(
async (payload: any) => {
userSubs$.unsubscribe();
})
或者将你的代码转换成类似这样的好方法:)
const eventref = this.db.database.ref(`branch/${branchId}/products`);
const snapshot = await eventref.once('value');
const productArray = snapshot.toJSON()
return productArray;
快乐编码