在Angular中等待异步函数完成

17

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

在调用this.getPrivateGroup()之前,需要完成This.getUserProfile,并且在调用this.loadGroupPosts()之前,需要完成this.getPrivateGroup()。我知道我可以在异步请求的回调函数中编写这些函数,但我想知道是否有一种方法可以保持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--! //

4
请提供每个函数的代码。 - Karim
getPrivateGroup 函数是什么样子的? - Prashant Pimpale
添加了这些函数。 - tilly
请查看这个Stack Overflow答案 - dream88
显示剩余2条评论
4个回答

23

您可以使用 async/await 与基本的 Promise。

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旁边添加async才能使其工作? - tilly
是的,完全忘记了 - 很抱歉。 - sandrooco
1
好的,我会测试一下并告诉你是否有效。 - tilly
2
请检查已编辑的答案 - 我认为使用适当的异步函数也可以解决问题。不确定您是否知道:通过从异步函数中返回某些内容,我们可以解决它创建的承诺(在 ngOnInit 中等待)。 - sandrooco

5
你可以使用 RxJS 并使用 switchMap,类似这样(语法未经检查):
getData(): Observable<string[]> {
  return this._userService.getUser()
    .pipe(
      switchMap(userInfo=> {
         return this.getPrivateGroup();
      }),
      catchError(this.someErrorHandler)
    );
}

1

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

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()});
        }

0

当您的订阅功能完成时,您还可以使用其第三部分。我不太确定这是否是一个干净的解决方案,但在我看来它是。

ngOnInit() {
this.getUserProfile();
}


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';
        }
    }, () => {
        // 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();
        }
    });
}

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)
    }, error => {
        console.log(error)
    }, () => {
        this.loadGroupPosts();
    })
}

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");
    });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接