1

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

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


服务.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;
        }
    );
}

组件.ts

categories = [];

constructor(private route: ActivatedRoute) { }

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

解析器.ts

constructor(private categoriesService: CategoriesService) { }

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

应用程序路由.module.ts

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

3 回答 3

4

Subscription从你的服务(以及你的解析器)返回一个,而不是返回一个 Observable。不要订阅服务。并指定返回值,以避免在脚下射击自己:

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

笔记

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

阅读HttpClient指南和RxJS quide

于 2019-03-31T15:07:54.693 回答
2

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

您可以将服务方法更新为

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

pull_categories方法将立即返回Observable,当您在组件(或任何地方)中订阅它时,将执行 http 调用并在您的subscribe部分中返回响应。

于 2019-03-31T15:12:02.767 回答
1

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

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

这将向您的组件返回一个承诺,您也可以通过以下方式使用它:

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

  }
}

于 2019-03-31T22:06:11.423 回答