【问题标题】:Angular2 Observable and PromiseAngular2 Observable 和 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) 可以让你的代码看起来像线性的,但它通过在下面使用回调来工作。

标签: angular promise rxjs observable


【解决方案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';

    这将有助于我们防止进一步的错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-15
      • 2017-07-29
      • 1970-01-01
      • 2018-10-18
      • 2017-11-01
      • 2018-02-05
      • 2016-11-30
      相关资源
      最近更新 更多