Подтвердить что ты не робот

Angular2 Наблюдаемый и обещающий

Я начал использовать Angular2 Observable, но я не могу найти что-то похожее на .then, которое я использовал с Promises.

Это то, что я хочу выполнить.

код от header.component.ts

public login() {
    this._user = AuthService.getInstance().login(this._loginInfo);
}

код от auth.service.ts

return this._httpClient.post('LoginAction', credentials)
  .map(res => res.json())
  .subscribe(user => {
    return new User(user);
  });

Функция promises, login возвращает Promise, которая в конечном итоге преобразуется в реальный ответ от сервера. Но с Observable это не сработает.

Есть ли способ сделать подобное? Я хочу избежать необходимости добавлять подписку внутри функции component login. Я хочу иметь возможность выполнять всю работу в сервисе и возвращать фактический объект в component.

Кроме того, я попытался создать Promise, с toPromise, но я продолжаю получать toPromise is not a function.

p.s. _httpClient - моя оболочка вокруг Angular2 http, в которой я готовлю запрос, добавляя некоторые заголовки и т.д.

изменить

return this._httpClient.post('LoginAction', credentials)
  .map(res => res.json())
  .toPromise().    <-- i keep getting that it is not a function
  then(user => {
    return new User(user);
});

выполнив это, мой компонент получит объект (который ему нужен), и в сервисе я мог бы делать дополнительные вещи (например, сохранять пользователя в localstorage, как только я его запустил).

И я переключился на Promise, потому что делать то же самое с Observable не работает (или я делаю это неправильно)?

Я вижу, что возвращаемый объект Observable (перед вызовом toPromise), но я действительно не вижу функцию toPromise.

4b9b3361

Ответ 1

Когда вы вызываете subscribe(...), возвращается Subscription, у которого нет toPromise(). Если вы переместите код с subscribe на map, вы можете использовать toPromise() вместо subscribe

return this._httpClient.post('LoginAction', credentials)
  .map(res => res.json())
  .map(user => {
    return new User(user);
  }).toPromise();

и вызывающий абонент получит Promise, где он может получить значение, используя

public login() {
    this._user = AuthService.getInstance().login(this._loginInfo)
    .then(result => {
      doSomething();
    });
}

но вы получите тот же результат, если вы опустите `.toPromise(), и вызывающий использует его как

public login() {
    this._user = AuthService.getInstance().login(this._loginInfo)
    .subscribe(result => {
      doSomething();
    });
}

где единственная разница subscribe() вместо then(), и если пользователь библиотеки предпочитает реактивный стиль, он предпочтет использовать subscribe(), как он привык.

Ответ 2

Вам нужно импортировать оператор Rx toPromise, например

import 'rxjs/add/operator/toPromise';

Ура!

Ответ 3

Из Angular2 документации

Мы рекомендуем добавить это в rxjs-extension.ts

```
// Observable class extensions 
   import 'rxjs/add/observable/of'; 
   import 'rxjs/add/observable/throw';

// Observable operators 
   import 'rxjs/add/operator/catch'; 
   import 'rxjs/add/operator/debounceTime'; 
   import 'rxjs/add/operator/distinctUntilChanged'; 
   import 'rxjs/add/operator/do'; 
   import 'rxjs/add/operator/filter'; 
   import 'rxjs/add/operator/map'; 
   import 'rxjs/add/operator/switchMap'; 
```

И импортируйте его в app.module.ts (Root Module) import './rxjs-extensions';

Это поможет нам предотвратить дальнейшую ошибку.