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,这是行不通的。

有没有办法做类似的事情?我想避免将订阅放在componentlogin 函数中。我希望能够在服务中完成所有工作,并将实际对象返回给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&lt;T&gt; | ((value: T) =&gt; void), error?: (error: any) =&gt; void, complete?: () =&gt; 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 不是函数”错误

Rxjs 过滤器运算符不适用于 Angular2 Observable

两个使用相同 Observable 的 angular2 服务