Angular 2 - 直接从Observable返回数据

时间:2022-03-01 10:54:47

I've been banging my head against this one trying to figure it out, and no amount of documentation I've been able to read has given me an answer to my question.

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

I have a service which is speaking directly to an API and returning an observable event which under normal circumstances I would subscribe to and do what I want with the data, however in a secondary service which utilizes the requests from the restful service, I need to be able to return values from the request.

我有一个服务,直接与API交谈,并返回一个可观察的事件,在正常情况下,我会订阅并做我想要的数据,但是在利用来自宁静服务的请求的二级服务中,我需要能够从请求中返回值。

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

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

In the quick example above, I want to know if there is any way I can return res from getSomething() within returnSomething(). If it's not achievable in this way, what is the alternative? I will add that the _restService is pretty heavily relied upon and I don't really want to start messing with that.

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

2 个解决方案

#1


35  

Since http calls and the like are async, you get an Observable instead of a synchronous value returned. You have to subscribe to it, and in the callback in there you get the data. There is no way around that.

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

One option would be to place your logic in the subscribe call

一种选择是将您的逻辑放在订阅调用中

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

But the way I like doing it is to add a callback, to inject the logic from outside (maybe a component, maybe another service):

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

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

And in your component or wherever:

在您的组件或任何地方:

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

#2


1  

I didn't use this myself, but I believe it should work in theory (:

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

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

Check subject docs for more info. You can use different types of subject, for example BehaviorSubject has value property you can access...

查看主题文档以获取更多信息。您可以使用不同类型的主题,例如,BehaviorSubject具有您可以访问的value属性...

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

Here's the working plunker...

这是工作的plunker ......

#1


35  

Since http calls and the like are async, you get an Observable instead of a synchronous value returned. You have to subscribe to it, and in the callback in there you get the data. There is no way around that.

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

One option would be to place your logic in the subscribe call

一种选择是将您的逻辑放在订阅调用中

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

But the way I like doing it is to add a callback, to inject the logic from outside (maybe a component, maybe another service):

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

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

And in your component or wherever:

在您的组件或任何地方:

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

#2


1  

I didn't use this myself, but I believe it should work in theory (:

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

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

Check subject docs for more info. You can use different types of subject, for example BehaviorSubject has value property you can access...

查看主题文档以获取更多信息。您可以使用不同类型的主题,例如,BehaviorSubject具有您可以访问的value属性...

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

Here's the working plunker...

这是工作的plunker ......