Angular 2 Firebase Observable 承诺不会返回任何东西
Posted
技术标签:
【中文标题】Angular 2 Firebase Observable 承诺不会返回任何东西【英文标题】:Angular 2 Firebase Observable to promise doesn't return anything 【发布时间】:2017-06-12 14:50:25 【问题描述】:我目前正在使用 AngularFire2 开发 Angular 2 项目,并且正在尝试将 FirebaseListObservable 转换为 Promise。我知道这没有多大意义,因为 Observables 更有用,但这个函数将成为另一个函数的一部分,其中多个 Promise 被链接。而且我不熟悉如何在一系列承诺中订阅 Observables ......该函数在服务中执行,但它似乎没有返回任何内容。 基本上,我想要做的是检查 Firebase 列表是否已经存在具有特定名称的对象并返回 true 或 false。
服务
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() 不会被执行。我想“那么”部分永远不会到达。另外,有没有办法在找到匹配项后停止 forEach 循环?
任何帮助将不胜感激,因为我根本找不到任何答案。
【问题讨论】:
在你的组件中是_dibbService
假设是 _usersService
?
是的,对不起!我在复制代码时切换了它们。
【参考方案1】:
问题在于toPromise
运算符将可观察对象转换为可解析为可观察对象最终值的承诺。这意味着 observable 必须在 promise 解决之前完成。
在 AngularFire2 中,list 和 object observables 不完整;每当数据库更改时,它们都会重新发出。
你可以使用first
操作符来解决这个问题,它获取第一个发出的值,然后完成组合的observable:
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();
【讨论】:
就在你认为你已经使用 Observables 足以理解它们的时候......非常感谢!成功了! 使用.first()时,订阅是否丢失? @Luis 否,first
是“普通”运算符,仍然需要调用 subscribe
。但是,toPromise
不是。它涉及对subscribe
的隐式调用,因为它将可观察对象转换为承诺。当 observable 完成时,返回的 Promise 解决。此外,当一个 observable 完成时,所有订阅者都会自动取消订阅。
为什么首先而不是take(1)
?
@Jimmy 如果源在没有发出值的情况下完成,first
将出错 - take(1)
不会。见***.com/a/42346203/6680611。除非我希望源代码有时会在不发射的情况下完成,否则我倾向于使用 first
。【参考方案2】:
我通过在收到第一个数据后以惰性方式取消订阅来解决这个问题:)
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;
快乐编码
【讨论】:
以上是关于Angular 2 Firebase Observable 承诺不会返回任何东西的主要内容,如果未能解决你的问题,请参考以下文章
Angular 2 - Firebase 在页面刷新时保持登录状态
Angular 2 Firebase Observable 承诺不会返回任何东西
找不到在 Angular 中导入 Firebase 身份验证
为啥我在尝试从 Angular 2 应用程序连接和查询 Firebase 数据库时收到此错误消息?