Angular 2 - 直接从Observable返回数据

问题描述 投票:29回答:3

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

我有一个直接与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非常依赖,我真的不想开始搞乱它。

typescript angular rxjs observable
3个回答
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
投票

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

// 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 ......


0
投票

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

 async getSomething() {
     try{
         return await this._restService.addRequest('object', 'method').run().toPromise()
      } catch (err){
       console.error(err);
	  }
  }
© www.soinside.com 2019 - 2024. All rights reserved.