Angular2 Observable 和 Promise
Posted
技术标签:
【中文标题】Angular2 Observable 和 Promise【英文标题】:Angular2 Observable and Promise 【发布时间】:2016-08-07 11:49:09 【问题描述】:我开始使用 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);
);
有了 Promise,login
函数将返回 Promise,最终将转换为来自服务器的实际响应。但是对于 Observable,这是行不通的。
有没有办法做类似的事情?我想避免将订阅放在component
的login
函数中。我希望能够在服务中完成所有工作,并将实际对象返回给component
。
另外,我尝试使用toPromise
创建Promise
,但我不断收到toPromise is not a function
。
附言_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);
);
通过这样做,我的组件将获得对象(这是它所需要的),并且在服务中我可以做其他事情(比如将用户保存到本地存储,一旦我登录他)。
然后我切换到Promise
,因为对Observable
做同样的事情不起作用(或者我做错了)?
我看到返回的对象是 Observable(在调用 toPromise 之前),但我确实没有看到 toPromise
函数。
【问题讨论】:
“我希望能够在服务中完成所有工作,并将实际对象返回给组件。” - 你不能这样做,因为httpClient.post
是异步的,所以如果你使用Promise你需要为then
函数提供回调,如果你使用RxJS Observable,你需要为subscribe
函数提供回调。 ES6 中的 async/await (ponyfoo.com/articles/understanding-javascript-async-await) 可以让你的代码看起来像线性的,但它通过在下面使用回调来工作。
【参考方案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()
,就像他习惯的那样。
【讨论】:
subscribe
返回 Disposable
而不是 订阅
subscribe(observerOrNext?: PartialObserver<T> | ((value: T) => void), error?: (error: any) => void, complete?: () => void): Subscription;
不知道你从哪里弄来的,看这里:github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/…
github.com/ReactiveX/rxjs/blob/…。也许Disposable
是 rxjs4。 Angular 使用 rxjs5。
@GünterZöchbauer 感谢您的帮助。请检查我编辑的问题,我试图澄清一点。【参考方案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
(根模块)
import './rxjs-extensions';
这将有助于我们防止进一步的错误。
【讨论】:
以上是关于Angular2 Observable 和 Promise的主要内容,如果未能解决你的问题,请参考以下文章
Angular2 http.get() ,map(), subscribe() 和 observable 模式 - 基本理解
Angular2 - 在另一个 Observable 中使用 Observable 返回方法的值
Typescript / Angular2:将 JSON 转换为与 Observable 和 JSONP 接口
Angular2 RxJS 得到“Observable_1.Observable.fromEvent 不是函数”错误