如何从请求中 return HttpClient 响应正文?

How to return HttpClient response body from a request?

我有一个组件,其内容依赖于 API 响应。我已经设置了解析器,但它仍然 returns 在我的数据准备好之前。

如何让我的 pull_categories() 函数等到收到响应正文,然后 return?而不是 returning 一个空对象,因为它不会等待甚至在我下面的例子中调用它。


service.ts

private _categories = [];

constructor(private http: HttpClient) { }

pull_categories() {
    this.http.post('https://myapi.com/something', null)
    .subscribe(
        data => {
            this._categories = data['response'];
            return this._categories;
        }
    );
}

component.ts

categories = [];

constructor(private route: ActivatedRoute) { }

ngOnInit() {
    this.route.data.subscribe(
        (data: Data) => {
            this.categories = data.categories;
        }
    );
}

resolver.ts

constructor(private categoriesService: CategoriesService) { }

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any {
    return this.categoriesService.pull_categories();
}

应用-routing.module.ts

{
    path: '',
    component: HomeComponent,
    resolve: {categories: CategoriesResolverService}
}

您正在从您的服务(以及您的解析器)returning Subscription,而不是 returning Observable。不要订阅服务。并指定 return 值,以避免搬起石头砸自己的脚:

getCategories(): Observable<Array<Category>> {
  return this.http.get<Something>('https://myapi.com/something').pipe(
    map(something => something.response)
  );
}

备注

  • 尊重命名约定
  • 使用 GET 来...获取数据,而不是 POST
  • 该方法实际上定义了什么 returns
  • 使用 HttpClient.get() 方法的泛型重载,允许指定响应主体的预期类型
  • 在服务中有一个实例字段是错误的(而且是不必要的)。

阅读 HttpClient guide, and the RxJS 指南。

首先,在 service.ts 中你不需要订阅,你应该在你想要实际使用数据的地方订阅。 subscribe 方法 returns Subscription,不是来自 http api 的响应。

您可以将您的服务方式更新为

pull_categories(): Observable<any> {
    return this.http.post('https://myapi.com/something', null);
}

pull_categories 方法将 return 立即与 Observable,当你在你的组件(或任何地方)订阅它时,http 调用将被执行并且响应将是 return在您的 subscribe 部分编辑。

从后端获取数据的另一种方法是不订阅数据,您也可以return返回一个 promise,然后在组件中使用 async await

pull_categories(): any {
    return this.http.post('https://myapi.com/something', null).toPromise();
} 

这将 return 向您的组件返回一个承诺,您也可以在其中以下列方式使用:

async getCategories() {
  try {
    const categories = await this.service.pull_categories();
  } catch (e) {

  }
}