Express 如何等待所有异步调用完成

Express 如何等待所有异步调用完成,express,promise,observable,es6-promise,nestjs,Express,Promise,Observable,Es6 Promise,Nestjs,我有一个NestJS应用程序,它可以与YoutubeAPI交互并从中加载视频。 有一种特别的方法很重要,它是loadVideos。方法本身内部有多个异步,完成所有操作后,我需要使用videoIdMap属性 private loadVideos( playListId: string, channel: Channel, nextPageToken: string, stopLoadingOnVideoId: string, ) { const base

我有一个NestJS应用程序,它可以与YoutubeAPI交互并从中加载视频。 有一种特别的方法很重要,它是
loadVideos
。方法本身内部有多个异步,完成所有操作后,我需要使用
videoIdMap
属性

private loadVideos(
    playListId: string,
    channel: Channel,
    nextPageToken: string,
    stopLoadingOnVideoId: string,
  ) {
    const baseUrl = YoutubeService.VIDEO_URL_SNIPPET_BY_ID + playListId;
    const response = this.httpService
      .get(nextPageToken ? baseUrl + '&pageToken=' + nextPageToken : baseUrl)
      .pipe(map((response) => response.data));
    response.subscribe((data) => {
      data.items.forEach((item) => {
        if (stopLoadingOnVideoId && item.snippet.resourceId.videoId === stopLoadingOnVideoId) {
          return;
        }        
        this.prepareVideoEntity(item.snippet, channel).then((partialVideo) =>              
          this.videoService.create(partialVideo).then((video) => {     
            this.videoIdMap[video.youtubeId] = video.id;
          }),
        );
      });      
      if (data.nextPageToken) {        
        this.loadVideos(
          playListId,
          channel,
          data.nextPageToken,
          stopLoadingOnVideoId,
        );
      }
    });
  }
对我来说,理想的解决方案是以某种方式使
loadVideos
异步,以便我以后可以执行以下操作:

public methodWhichCallLoadVideos(): void {
  await loadVideos(playListId, channel, null, stopLoadingOnVideoId)
  // My code which have to be executed right after videos are loaded
}

我尝试的每一个解决方案都以
这个结尾。videoIdMap
是空对象,或者有编译问题,所以任何想法都是非常受欢迎的。

您可以切换到承诺而不是可观察的,从而将该方法转换为异步方法,只要
数据
具有
下一个getoken

private async loadVideos(
        playListId: string,
        channel: Channel,
        nextPageToken: string,
        stopLoadingOnVideoId: string,
    ) {
        const baseUrl = YoutubeService.VIDEO_URL_SNIPPET_BY_ID + playListId;
        const response = await this.httpService
            .get(nextPageToken ? url + '&pageToken=' + nextPageToken : url).toPromise();
        const { data } = response;
        for (const item of data.items) {
            if (stopLoadingOnVideoId && item.snippet.resourceId.videoId === stopLoadingOnVideoId) {
                continue;
            }
            const partialVideo = await this.prepareVideoEntity(item.snippet, channel);
            const video = await this.videoService.create(partialVideo)
            this.videoIdMap[video.youtubeId] = video.id;
        }
        if (data.nextPageToken) {
            await this.loadVideos(
                playListId,
                channel,
                data.nextPageToken,
                stopLoadingOnVideoId,
            );
        }
    }
然后,您只需等待
加载视频(…)


为了“等待”加载视频,您需要将其设置为“异步”。为此,它必须返回一个承诺,而Nest的HttpService返回一个可观察的承诺。检查此问题:已接受+竖起大拇指!这是我一直在寻找的又好又干净的代码。我只想问一下,为什么将
forEach
替换为
for
loop?很乐意为您提供帮助-
forEach
不会等待在循环内部完成的异步调用。它将只是发射,而不是等待承诺的解决。下面有一篇文章对此进行了详细解释:
private async initVideoIdMap(...) {
  await this.loadVideos(...);
  // this.videoIdMap should be correctly populated at this point
}