Angular NgOnInit 在另一个方法之前执行

Angular NgOnInit executing method before another

我有一个 angular 应用程序,我试图在其中获取图像轮播的一组源。 我目前是如何设置的 我有一个“getUrls()”方法来从数据库中获取 url,就像这样

http.service.ts:

getUrls() {
    this.http
      .get<string[]>(
        '<DATABASE_LINK>'
      )
      .subscribe((imageUrls: string[]) => {
        this.carouselService.setUrls(imageUrls);
      });
  }

该方法调用方法“setUrls”将它们设置到存储在服务中的数组中

carousel.service.ts:

  urls: string[] = [];

  constructor() {}

  setUrls(urls: string[] | []) {
    this.urls = urls || [];
    debugger;
  }

  getImages() {
    debugger;
    return this.urls;
  }

然后在 carousel 组件内部,我在 ngOnInit

中调用了之前的两个方法

图片-carousel.component.ts:

  ngOnInit(): void {
    this.httpService.getUrls();
    this.images = this.cService.getImages();
  }

这将分配由“setUrls()”方法设置的值,但由于某种原因,它在设置 Urls 之前到达“getImages()”方法。

我通过将“getImages()”行放入一个单独的方法并单击一个按钮来调用它来让它工作,这样我就可以确保一切都按正确的顺序工作并且确实如此,但是我希望它在组件初始化时完成所有这些工作。

我确信我遗漏了一些东西,所以任何东西都有帮助,即使我必须进行大量重构。

我尝试在“getUrls()”方法中使用“.pipe(tap()”而不是订阅,但它永远不会调用“setUrls()”方法。

由于 getUrls() 以异步方式执行其工作,您不知道它何时完成并且 return imageUrls。你必须稍微重构你的代码,像这样

getUrls():Observable<string[]> {
return this.http
  .get<string[]>(
    '<DATABASE_LINK>'
  );
  }

并且您的 ngOnInit 方法将像这样更新

  ngOnInit(): void {
this.httpService.getUrls()
.subscribe((imageUrls:string[])=>
 {
   this.images = imageUrls;
  });
 }

服务getUrls()中的函数是一个异步函数。因此,您必须等待它被解决。您可以使用可观察对象来实现这一点。您只需订阅 getUrls() 并将获取图像函数调用放在订阅块中。

由于getUrls()正在执行异步任务http.get,您必须等待异步任务完成后才能获取图像。

所以可能的解决方案之一是,您可以 return 从您的 http.service.ts 服务和内部组件中观察到 ngOnInit 您可以在订阅中获取图像。

http.service.ts:

getUrls() {
    return this.http
      .get<string[]>(
        '<DATABASE_LINK>'
      )
      .pipe(
         map((imageUrls: string[]) => {
            this.carouselService.setUrls(imageUrls);
         })  
       );
  }

carousel.service.ts:

  urls: string[] = [];

  constructor() {}

  setUrls(urls: string[] | []) {
    this.urls = urls || [];
    debugger;
  }

  getImages() {
    debugger;
    return this.urls;
  }

image-carousel.component.ts:

ngOnInit(): void {
    this.httpService
        .getUrls()
        .subscribe(
          () => {
             this.images = this.cService.getImages();
          }
        );
  }

http.service.ts:

getUrls() {
    return this.http
      .get<string[]>(
        '<DATABASE_LINK>'
      )
      .pipe(
         map((imageUrls: string[]) => {
            this.carouselService.setUrls(imageUrls);
         })  
       );
  }

carousel.service.ts:

  urls: string[] = [];

  constructor() {}

  setUrls(urls: string[] | []) {
    this.urls = urls || [];
    debugger;
  }

  getImages() {
    debugger;
    return this.urls;
  }

image-carousel.component.ts:

ngOnInit(): void {
    this.httpService
        .getUrls()
        .subscribe(
          () => {
             this.images = this.cService.getImages();
          }
        );
  }