关于typescript:Angular 2 Firebase可观察到的Promise不会返回任何内容

Angular 2 Firebase Observable to promise doesn't return anything

我目前正在使用AngularFire2进行Angular 2项目,并且正在尝试将FirebaseListObservable转换为Promise。我知道这没有多大意义,因为Observables更有用,但是此函数将是另一个链接了多个promise的函数的一部分。而且我不熟悉如何在promise链中订阅Observables ...该函数在服务中执行,但是似乎不返回任何内容。
基本上,我想做的是检查Firebase列表中是否存在具有特定名称的对象,并返回true或false。

服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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();
}

成分

1
2
3
4
5
6
constructor(private _usersService: UsersService) { }

check(name) {
 this._usersService.nameExists(name)
  .then(bool => console.log(bool));
}

因此,当匹配时,该函数将执行并在打印到控制台时似乎正常工作。但是,该组件中的console.log()不会执行。我猜"那"部分永远都不会达到。另外,找到匹配项后,是否有办法停止forEach循环?

任何帮助将不胜感激,因为我根本找不到任何答案。


问题在于toPromise运算符将可观察对象转换为可分解为可观察对象的最终值的Promise。这意味着可观察者必须在诺言解决之前完成。

在AngularFire2中,列表和对象的可观察对象不完整;每当数据库更改时,它们都会重新发出。

您可以使用first运算符解决问题,该运算符采用第一个发出的值,然后完成组成的可观察项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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();


在第一个数据以惰性方式接收后,我通过取消订阅来解决了这个问题:)

1
2
3
4
const userSubs$ = this.db.object(`branch/${branchId}/products`).subscribe(
                     async (payload: any) => {
                      userSubs$.unsubscribe();
                       })

或者将您的代码转换为类似的好方法:)

1
2
3
4
 const eventref = this.db.database.ref(`branch/${branchId}/products`);
  const snapshot = await eventref.once('value');
  const productArray = snapshot.toJSON()
  return productArray;

快乐编码