javascript 等待异步函数在 Angular 中完成

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/53817629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 10:17:55  来源:igfitidea点击:

wait for asynchronous functions to finish in Angular

javascriptangularasynchronous

提问by tilly

So I was working on a new component in Angular and in the ngOninit I have the following asynchronous functions below...

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

This.getUserProfile needs to be finished before I can call this.getPrivateGroup() and this.getPrivateGroup() needs to be finished before I can call this.loadGroupPosts(). I know I could write these functions inside the callback of the asynchronous requests, but I was wondering if there is a way to keep it in ngOnInit to keep it cleaner?

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

Anyone has an idea?

有人有想法吗?

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--! //

回答by sandrooco

You can use basic promises with async/await.

您可以将基本承诺与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;
      });

}

}

回答by DeborahK

You could instead leverage RxJS and use a switchMap something like this (NOT syntax checked):

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

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

回答by Aragorn

One way to do is, return the Observable instead of subscribing in the getPrivateGroup()

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

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

  }

And then, subscribe to the data where you want the chain the this.loadGroupPosts()

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

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