简体   繁体   English

如何从实现可观察的函数返回数据

[英]How to return data from function implementing observable

I have a requirement like below我有一个像下面这样的要求

I have a function (in let say file2.ts) which makes observable GET HTTP requests and the returns AppResponse object filled with the HTTP response.我有一个函数(比如 file2.ts),它可以生成可观察的 GET HTTP 请求,并返回填充了 HTTP 响应的 AppResponse 对象。 here is the code.这是代码。 i want appResponse object in file1.ts to be populated with file2.ts get1 call.我希望 file1.ts 中的 appResponse 对象用 file2.ts get1 调用填充。 How to achieve this?如何实现这一目标?

**file1.ts**

  getProfile() {
    this.appResonse = this.file1.get1(endPoint);
  }

**file2.ts**
  get1(endPoint: string): AppResponse {
    let appResponse = new AppResponse();

    this.httpClient.get<IHttpResponse>(url).subscribe((httpResponse: IHttpResponse) => {
        appResponse.data = httpResponse.data;
    });

    return appResponse;
  }

Although the answer by akirus answers your question, i want to add some points, as it seems that you are not familiar with async and observable concepts...虽然 akirus 的回答回答了你的问题,但我想补充几点,因为你似乎不熟悉异步和可观察的概念......

  1. A http request is an async call. http 请求是async调用。 That means when you make a http request, the browser will not wait for the response, but will continue to execute code after this call.这意味着当您发出 http 请求时,浏览器不会等待响应,而是会在此调用后继续执行代码。 And when the response is available, the the call back or subscribe method is invoked.当响应可用时,调用回调或订阅方法。

  2. So in the above code snippet of yours, first this line is executed in the method:所以在你上面的代码片段中,首先在方法中执行这一行:

let appResponse = new AppResponse();让 appResponse = new AppResponse();

Then a request is sent to the server.然后向服务器发送请求。 Which is essentially this code本质上是这个代码

this.httpClient.get(url) this.httpClient.get(url)

Then as mentioned in point 1, the next instruction is executed which is然后如第 1 点所述,执行下一条指令,即

return appResponse;返回应用响应;

Then some point of time, the request would complete and the subscribe method is called.然后某个时间点,请求将完成并调用 subscribe 方法。 Executing the following code执行以下代码

appResponse.data = httpResponse.data; appResponse.data = httpResponse.data;

But since you are not waiting till this point to return data to caller from file1.ts.但是由于您没有等到此时才将数据从 file1.ts 返回给调用者。 The data would be undefined in the AppResponse数据将在 AppResponse 中未定义

this.appResonse = this.file1.get1(endPoint); this.appResonse = this.file1.get1(endPoint);

  1. So When you want to get data from such async calls, you will have to return Promise or Observable which means, the data will be available at some point in future and the calling method will be notified when data is available.因此,当您想从此类异步调用中获取数据时,您必须返回 Promise 或 Observable,这意味着数据将在未来某个时间可用,并且在数据可用时将通知调用方法。 So in your case You will have to return a observable from file2.ts and subscribe in file1.ts因此,在您的情况下,您必须从file2.ts返回一个 observable 并在file1.ts订阅

  2. So you code could be所以你的代码可能是

**file1.ts**

  getProfile(): void {
    this.file1.get1(endPoint).subscribe(appResponse => this.appResponse = appResponse);
  }

**file2.ts**
  get1(endPoint: string): Observable<AppResponse> {
    return this.httpClient.get<IHttpResponse>(url)
                   .pipe(
                      map((httpResponse: IHttpResponse) => {
                             let appResponse = new AppResponse();
                             appResponse.data = httpResponse.data;
                             return appResponse;
                      });
                    );
  }

The normal approach is to have:通常的方法是:

return this.httpClient.get(url);

in file2 and then subscribe to that response in file1, setting the appResponse to the response data.在 file2 中,然后在 file1 中订阅该响应,将appResponse设置为响应数据。

If for some reason you really need to subscribe in file2 then you can either return a promise that resolves when the data is retrieved or have some sort of observer/subscriber pair that you subscribe to in file1 when the data is received.如果由于某种原因您确实需要在 file2 中订阅,那么您可以返回一个在检索数据时解析的承诺,或者在收到数据时在 file1 中订阅某种观察者/订阅者对。

All of these are just extra steps that can help you save that data in file2 while also sending it to file1 but if that is not the case then simply subscribing in file1 should be the go to approach.所有这些都只是额外的步骤,可以帮助您将数据保存在 file2 中,同时还将其发送到 file1,但如果不是这种情况,那么只需在 file1 中订阅就应该是首选方法。

Edit: Example of the alternative options编辑:替代选项示例

file1.ts文件1.ts

export class ComponentOne{

    appResponse$: Observable<AppResponse>;
    
    constructor(private serviceOne: ServiceOne){
        this.appResponse$ = this.serviceOne.get1();
        
        this.appResponse$.pipe(
            map(httpResponse => httpResponse.data)
        ).subscribe(data =>{
            console.log(data);
        });
    }
    
}

file2.ts文件2.ts

@Injectable({
    providedIn: 'root'
})
export class ServiceOne{
    get1(endPoint: string): Observable<AppResponse> {
        return this.httpClient.get<IHttpResponse>(url);
    }
}

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

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