简体   繁体   English

Angular2可观察和承诺

[英]Angular2 Observable and Promise

I started using Angular2 Observable , but I can't find something similar to .then that I used with Promises . 我开始使用Angular2 Observable ,但我找不到类似的东西.then ,我所使用Promises

This is what I want to accomplish. 这就是我要完成的。

code from header.component.ts 来自header.component.ts的代码

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

code from auth.service.ts 来自auth.service.ts的代码

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

With promises, login function would return Promise, that would eventually transform to actual response from server. 有了promise, login功能将返回Promise,最终将转换为服务器的实际响应。 But with Observable this won't work. 但是使用Observable,这将无法工作。

Is there a way to do similar thing? 有没有办法做类似的事情? I want to avoid need of putting subscribe inside component 's login function. 我想避免需要在componentlogin功能中放入订阅。 I want to be able to do all the work in service, and to return actual object to component . 我希望能够完成服务中的所有工作,并将实际对象返回给component

Also, I tried to create Promise , with toPromise , but I keep getting toPromise is not a function . 另外,我尝试使用toPromise创建Promise ,但是我一直在获取toPromise is not a function

ps _httpClient is my wrapper around angular2 http in which I prepare request by adding some headers etc. ps _httpClient是我对angular2 http的包装,在其中我通过添加一些标头等来准备请求。

edit 编辑

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

by doing this, my component will get object (which is what it need), and in service i could do additional things (like saving user to localstorage, once I logged him). 通过这样做,我的组件将获得对象(这是它所需要的),并且在服务中,我可以做其他事情(例如,一旦我登录他,将用户保存到localstorage)。

And I switched to Promise , because doing same with Observable is not working (or I am doing it wrong)? 我切换到Promise ,因为对Observable进行同样的操作不起作用(或者我做错了)?

I see that returned object is Observable (before calling toPromise), but I don't see toPromise function indeed. 我看到返回的对象是可观察的(在调用toPromise之前),但我确实没有看到toPromise函数。

When you call subscribe(...) a Subscription is returned which doesn't have a toPromise() . 当你调用subscribe(...)一个Subscription返回其不具有toPromise() If you move the code from subscribe to map you can use toPromise() instead of subscribe 如果将代码从subscribe移动到map ,则可以使用toPromise()代替subscribe

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

and the caller will get a Promise where he can get the value using 呼叫者将获得一个Promise ,他可以在其中使用

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

but you get the same result if you omit `.toPromise() and the caller uses it like 但是如果省略`.toPromise()并且调用方像

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

where the only difference is subscribe() instead of then() and if the user of the library prefers the reactive style he will prefer using subscribe() like he is used to. 唯一的区别在于, subscribe()而不是then()并且如果库的用户更喜欢反应式样式,他将更喜欢像以前一样使用subscribe()

You need to import the Rx toPromise operator like 您需要像这样导入Rx toPromise运算符

import 'rxjs/add/operator/toPromise';

Cheers! 干杯!

From Angular2 documentation 从Angular2文档中

We are advise to add this in rxjs-extension.ts 我们建议将其添加到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'; 
```

And import it at app.module.ts (Root Module) import './rxjs-extensions'; 并将其导入到app.module.ts (根模块) import './rxjs-extensions';

This will help us to prevent further error. 这将有助于我们防止进一步的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM