繁体   English   中英

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

[英]How to return data from function implementing observable

我有一个像下面这样的要求

我有一个函数(比如 file2.ts),它可以生成可观察的 GET HTTP 请求,并返回填充了 HTTP 响应的 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;
  }

虽然 akirus 的回答回答了你的问题,但我想补充几点,因为你似乎不熟悉异步和可观察的概念......

  1. http 请求是async调用。 这意味着当您发出 http 请求时,浏览器不会等待响应,而是会在此调用后继续执行代码。 当响应可用时,调用回调或订阅方法。

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

让 appResponse = new AppResponse();

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

this.httpClient.get(url)

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

返回应用响应;

然后某个时间点,请求将完成并调用 subscribe 方法。 执行以下代码

appResponse.data = httpResponse.data;

但是由于您没有等到此时才将数据从 file1.ts 返回给调用者。 数据将在 AppResponse 中未定义

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

  1. 因此,当您想从此类异步调用中获取数据时,您必须返回 Promise 或 Observable,这意味着数据将在未来某个时间可用,并且在数据可用时将通知调用方法。 因此,在您的情况下,您必须从file2.ts返回一个 observable 并在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;
                      });
                    );
  }

通常的方法是:

return this.httpClient.get(url);

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

如果由于某种原因您确实需要在 file2 中订阅,那么您可以返回一个在检索数据时解析的承诺,或者在收到数据时在 file1 中订阅某种观察者/订阅者对。

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

编辑:替代选项示例

文件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);
        });
    }
    
}

文件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