如何 return 来自实现可观察函数的数据

How to return data from function implementing observable

我有如下需求

我有一个函数(比方说 file2.ts),它发出可观察的 GET HTTP 请求和填充了 HTTP 响应的 returns AppResponse 对象。这是代码。我希望 file1.ts 中的 appResponse 对象被 file2.ts get1 调用填充。如何实现?

**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;
  }

正常的做法是:

return this.httpClient.get(url);

在 file2 中,然后在 file1 中订阅该响应,将 appResponse 设置为响应数据。

如果出于某种原因你真的需要在 file2 中订阅,那么你可以 return 一个在检索数据时解析的承诺,或者有某种你订阅的 observer/subscriber 对收到数据时的file1.

所有这些只是额外的步骤,可以帮助您将数据保存在 file2 中,同时将其发送到 file1,但如果不是这种情况,那么简单地订阅 file1 应该是可行的方法。

编辑:Example 个替代选项

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

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

虽然akirus的回答回答了你的问题,但我想补充几点,因为你似乎对async和observable的概念不熟悉...

  1. 一个 http 请求是一个 async 调用。也就是说当你发出一个http请求时,浏览器不会等待响应,而是会在这个调用之后继续执行代码。当响应可用时,将调用回调或订阅方法。

  2. 所以在你上面的代码片段中, 首先这一行在方法中执行:

let appResponse = new AppResponse();

然后向服务器发送请求。本质上就是这段代码

this.httpClient.get(url)

然后如第1点所述,执行下一条指令

return appResponse;

然后某个时间点,请求将完成并且订阅方法是 叫。执行以下代码

appResponse.data = httpResponse.data;

但是由于您没有等到此时才将 return 数据发送给来自 file1.ts。 AppResponse

中的数据未定义

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

  1. 所以当你想从这样的异步调用中获取数据时,你将不得不 return Promise 或 Observable ,这意味着数据将在未来的某个时间可用并且调用方法将在数据可用时得到通知。 因此,在您的情况下,您必须 return 来自 file2.ts 的可观察对象并订阅 file1.ts

  2. 所以你的代码可以是

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