【问题标题】:Angular 2.0 - converting promise chaining to ObservablesAngular 2.0 - 将承诺链转换为 Observables
【发布时间】:2016-03-30 21:59:42
【问题描述】:

我正在将 NG 1.X 服务转换为 NG 2.0。

我的 NG 1.X 服务具有承诺链(简化):

dataService.search = function(searchExp) {
      return this.getAccessToken()
      .then(function(accesstoken) {
        var url = $interpolate('https://my-api-url?q={{search}}&{{accesstoken}}')({search: searchExp, accesstoken: accesstoken});
        return $http({
          url: url,
          method: 'GET',
          cache: true
        });
      }).then(function(response) {
        return response.data;
      });
    };

我想将 search 服务转换为 Angular 2.0 服务,使用 http 并返回 Observable。我更喜欢将 getAccessToken 服务保持不变,作为 NG 1.X 服务,它会返回一个承诺。

我正在考虑在旧的“承诺”服务上使用Observable.fromPromise

我该怎么做?我怎样才能把这两个链接起来?

编辑

澄清一下,我希望它是这样的:

dataService.search = function(searchExp) {
 return this.getAccessToken()
        .then(function(accesstoken) {
           //Here I want to use:
           // this.http.get(url).subscribe(() => ...)
          });
        };

【问题讨论】:

  • Observable.fromPromise(dataService.search)?
  • 这很明显。我的问题是如何从函数中返回这个值?我不能把它锁起来!

标签: javascript angularjs reactive-programming angular rxjs


【解决方案1】:

你应该让search 方法返回 Observable 对象。像这样的:

dataService.search = function(searchExp) {

    var promise = new Promise((resolve, reject) => {
        this.getAccessToken()
            .then(accesstoken => {
                return this.http.get('data.json')
                    .map(response => response.json())
                    .subscribe(data => resolve(data), err => reject(err))
            })
    });

    return PromiseObservable.create(promise); // Observable.fromPromise(promise)
};

【讨论】:

  • 感谢您的回答。我的问题是如何将第二个承诺更改为使用 Observable 的 Angular 2.0 http
  • 你是说内部$http?
  • 只返回 observable 作为内部承诺。然后做return Observable.fromPromise(promise);。查看更新的答案。
  • 这很有趣。我试过了,但是在调用我拥有的服务的组件中:`dataService.search(data).subscribe((res) => //res here is an Observable!!)
  • 是的,我的版本也不行。我设置了一个似乎效果更好的实验。检查更新版本。这里还有一个演示:plnkr.co/edit/VPnCTXV6lVayIp4HJ8pV?p=info
【解决方案2】:

我将@dfsq 的 Plunker 转换为 beta.0。 map() 如果不导入它似乎不再可用(但我们在这里不需要它)。

import {Component, Injectable} from 'angular2/core';
import {HTTP_PROVIDERS, Http} from 'angular2/http';
import {PromiseObservable} from 'rxjs/observable/fromPromise';

@Injectable()
export class DataService {
  constructor(private _http: Http, private _accessService: AccessService) {} 
  search(searchExp) {
    var promise = new Promise((resolve, reject) => {
      this._accessService.getAccessToken()  // see Plunker for AccessService
        .then(accessToken => {
          return this._http.get('data.json')  // use accessToken here
            .subscribe(res => resolve(res.json()), err => reject(err));
        });
    });
    return PromiseObservable.create(promise);
  }
}
@Component({
  selector: 'my-app',
  providers: [HTTP_PROVIDERS, AccessService, DataService],
  template: `<h2>Data loaded</h2><pre>{{data | json}}</pre>
  `
})
export class AppComponent {
  data: any;
  constructor(private _dataService: DataService) { 
    console.clear();
  } 
  ngOnInit() {
    this._dataService.search('test')
      .subscribe(res => {
        this.data = res; 
      });
  }
}

beta.0 Plunker

【讨论】:

    猜你喜欢
    • 2015-02-25
    • 2018-05-04
    • 2018-01-10
    • 1970-01-01
    • 2014-08-27
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多