Tìm kiếm trang web

typescript - Angular 2 Firebase Observable thành promise không trả về gì cả


Hiện tại tôi đang làm việc trên một dự án Angular 2 với AngularFire2 và tôi đang cố gắng chuyển đổi một FirebaseListObservable thành Promise. Tôi biết điều này không hợp lý lắm vì Observables hữu ích hơn, nhưng chức năng này sẽ là một phần của một chức năng khác, nơi nhiều promise được nối chuỗi với nhau. Và tôi không quen với việc đăng ký (subscribe) các Observables trong một chuỗi các promise... Chức năng này được thực thi trong service, tuy nhiên dường như nó không trả về gì cả. Về cơ bản, điều tôi muốn làm là kiểm tra trong một danh sách Firebase xem một đối tượng với tên nhất định đã tồn tại hay chưa và trả về true hoặc false.

Dịch vụ

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();
}

thành phần

constructor(private _usersService: UsersService) { }

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

Vì vậy, hàm được thực thi và dường như hoạt động đúng khi nó in ra console, khi có một kết quả trùng khớp. Tuy nhiên, console.log() trong component không được thực thi. Tôi đoán phần "then" chưa bao giờ được thực hiện. Ngoài ra, có cách nào để dừng vòng lặp forEach khi đã tìm thấy kết quả trùng khớp không?

Bất kỳ sự giúp đỡ nào cũng sẽ được đánh giá cao vì tôi hoàn toàn không thể tìm thấy câu trả lời nào cho việc này.

Câu trả lời #1

Vấn đề là toán tử toPromise chuyển observable thành một promise mà sẽ được giải quyết thành giá trị cuối cùng của observable. Điều đó có nghĩa là observable phải hoàn tất trước khi promise được giải quyết.

Trong AngularFire2, các observable danh sách và đối tượng không hoàn tất; chúng phát lại bất cứ khi nào cơ sở dữ liệu thay đổi.

Bạn có thể giải quyết vấn đề bằng cách sử dụng toán tử first, toán tử này lấy giá trị được phát ra đầu tiên và sau đó hoàn tất observable đã ghép:

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();

Bài viết liên quan