Angular 2 - 直接从Observable返回数据

时间:2016-06-16 18:41:04

标签: typescript angular rxjs observable

我一直在试图解决这个问题,而且我已经能够阅读的任何文件都没有给我答案。

我有一个直接与API对话并返回可观察事件的服务,在正常情况下我会订阅并按照数据执行我想要的操作,但是在使用来自restful服务的请求的辅助服务中,我需要能够从请求中返回值。

getSomething() {
    return this._restService.addRequest('object', 'method').run()
        .subscribe(
            res => {
                res;
            },
            err => {
                console.error(err);
            }
        );
}

returnSomething() {
    return this.getSomething();
}

在上面的简单示例中,我想知道是否有任何方法可以在res内从getSomething()返回returnSomething()。如果以这种方式无法实现,那么替代方案是什么?我将补充说,_restService非常依赖,我真的不想开始搞乱它。

3 个答案:

答案 0 :(得分:41)

由于http调用等是异步的,因此会得到Observable而不是返回的同步值。你必须订阅它,并在那里的回调中获得数据。没有办法解决这个问题。

一种选择是将您的逻辑放在subscribe电话

getSomething() {
    return this._restService.addRequest('object', 'method').run()
        .subscribe(
            res => {
                // do something here
                res;
            },
            err => {
                console.error(err);
            }
        );
}

但我喜欢这样做的方法是添加一个回调,从外部注入逻辑(可能是一个组件,也许是另一个服务):

getSomething(callback: (data) => void) {
    return this._restService.addRequest('object', 'method').run()
        .subscribe(
            res => {
                callback(res);
            },
            err => {
                console.error(err);
            }
        );
}

在您的组件或任何地方:

this._yourService.getSomething((data) => {
    // do something here
    console.log(data);
});

答案 1 :(得分:1)

我自己并没有使用它,但我相信它应该在理论上有用(:

// service.ts
getSomething() {
  let subject: Subject = new Subject();
  this._restService.addRequest('object', 'method').run()
    .subscribe(subject);
  return subject;
}

// this can be removed (;
returnSomething() {
  return this.getSomething();
}

// component.ts
ngOnInit() {
  this.service.returnSomething()
    .subscribe(res => console.log(res), err => console.log(err));
}

查看subject docs了解详情。您可以使用不同类型的主题,例如 BehaviorSubject 具有value属性,您可以访问...

ngOnInit() {
  // if you use BehaviorSubject
  this.service.returnSomething().value
}

这里是working plunker ...

答案 2 :(得分:0)

我有一个类似的问题。我的解决方案是使用.toPromise()将可观察对象转换为一个Promise(并使用async-等待返回它并捕获错误)。您可以将代码转换为以下内容:

 async getSomething() {
     try{
         return await this._restService.addRequest('object', 'method').run().toPromise()
      } catch (err){
       console.error(err);
	  }
  }