等待异步函数在 Angular 中完成

Posted

技术标签:

【中文标题】等待异步函数在 Angular 中完成【英文标题】:wait for asynchronous functions to finish in Angular 【发布时间】:2019-05-17 23:05:16 【问题描述】:

所以我在 Angular 中开发一个新组件,在 ngOninit 中我有以下异步函数...

This.getUserProfile 需要在我调用 this.getPrivateGroup() 之前完成,并且 this.getPrivateGroup() 需要在我调用 this.loadGroupPosts() 之前完成。我知道我可以在异步请求的回调中编写这些函数,但我想知道是否有办法将其保留在 ngOnInit 中以使其更清洁?

有人有想法吗?

ngOnInit() 

    this.getUserProfile();

    // my-workplace depends on a private group and we need to fetch that group and edit
    // the group data before we proceed and get the group post
    if (this.isItMyWorkplace) 
      this.getPrivateGroup();
    
    this.loadGroupPosts();
  

getUserProfile() 
    this._userService.getUser()
      .subscribe((res) => 
        this.user = res.user;
        console.log('log user', this.user);
        this.profileImage = res.user['profile_pic'];
        this.profileImage = this.BASE_URL + `/uploads/$this.profileImage`;
      , (err) => 
        this.alert.class = 'alert alert-danger';
        if (err.status === 401) 
          this.alert.message = err.error.message;
          setTimeout(() => 
            localStorage.clear();
            this._router.navigate(['']);
          , 3000);
         else if (err.status) 
          this.alert.class = err.error.message;
         else 
          this.alert.message = 'Error! either server is down or no internet connection';
        
      );
  



getPrivateGroup() 
    console.log('user check', this.user);
    this.groupService.getPrivateGroup(`$this.user.first_name$this.user.last_name`)
      .subscribe((group) => 
          console.log('received response', group)
    )
  

 // !--LOAD ALL THE GROUP POSTS ON INIT--! //
  loadGroupPosts() 
    this.isLoading$.next(true);

    this.postService.getGroupPosts(this.group_id)
      .subscribe((res) => 
        // console.log('Group posts:', res);
        this.posts = res['posts'];
        console.log('Group posts:', this.posts);
        this.isLoading$.next(false);
        this.show_new_posts_badge = 0;
      , (err) => 
        swal("Error!", "Error while retrieving the posts " + err, "danger");
      );
  
  // !--LOAD ALL THE GROUP POSTS ON INIT--! //

【问题讨论】:

贴出各个函数的代码 getPrivateGroup 函数长什么样子? 好的,我发一下 新增功能。 除非你用 @ 提醒他们,否则他们不会收到通知 【参考方案1】:

一种方法是,返回 Observable 而不是订阅 getPrivateGroup()

getPrivateGroup() 
    console.log('user check', this.user);
    return this.groupService.getPrivateGroup(`$this.user.first_name$this.user.last_name`)

  

然后,订阅你想要链接的数据this.loadGroupPosts()

     if (this.isItMyWorkplace) 
          this.getPrivateGroup().subscribe(group => 
          this.group = group; //you probably want to assign the group data
          this.loadGroupPosts());
        

【讨论】:

【参考方案2】:

您可以通过async/await 使用基本承诺。

async ngOnInit() 

    await this.getUserProfile(); // <-- 1. change

    // my-workplace depends on a private group and we need to fetch that group and edit
    // the group data before we proceed and get the group post
    if (this.isItMyWorkplace) 
      this.getPrivateGroup();
    
    this.loadGroupPosts();
  

async getUserProfile() 
    this._userService.getUser()
      .subscribe((res) => 
        this.user = res.user;
        console.log('log user', this.user);
        this.profileImage = res.user['profile_pic'];
        this.profileImage = this.BASE_URL + `/uploads/$this.profileImage`;
        return true; // <-- this
      , (err) => 
        this.alert.class = 'alert alert-danger';
        if (err.status === 401) 
          this.alert.message = err.error.message;
          setTimeout(() => 
            localStorage.clear();
            this._router.navigate(['']);
          , 3000);
         else if (err.status) 
          this.alert.class = err.error.message;
         else 
          this.alert.message = 'Error! either server is down or no internet connection';
        
        throw err;
      );

【讨论】:

感谢您的回复。是否有可能我必须在 ngOninit 旁边添加异步才能使其工作? 是的,完全忘记了,抱歉。 很好,我会测试一下,如果它有效,请告诉你 检查编辑的答案 - 我认为它也应该与适当的异步功能一起使用。不确定你是否知道:通过从异步函数中返回一些东西,我们解决了它创建的承诺(在 ngOnInit 中等待)。【参考方案3】:

您可以改为利用 RxJS 并使用类似这样的 switchMap(未检查语法):

getData(): Observable<string[]> 
  return this._userService.getUser()
    .pipe(
      switchMap(userInfo=> 
         return this.getPrivateGroup();
      ),
      catchError(this.someErrorHandler)
    );

【讨论】:

以上是关于等待异步函数在 Angular 中完成的主要内容,如果未能解决你的问题,请参考以下文章

量角器:失败:超时等待异步角度任务在11秒后完成

Angular等待所有订阅完成

量角器 - 等待异步完成

在映射下一项之前,异步等待映射不等待异步函数在映射函数内部完成

Angular 2如何让子组件等待异步数据准备好

如何让 Lambda 函数等待异步操作完成?