简体   繁体   English

如何在ngOnInit中使用await / async?

[英]How to use await/async in ngOnInit?

I am trying to call a function in the ngOnInit() and feed it two values. 我试图在ngOnInit()调用一个函数并为它提供两个值。 So this is the function I'm trying to call inside the ngOnInit : this.complexWordIdentification(this.postIWant, this.theHardWords); 所以这是我试图在ngOnInit调用的ngOnInitthis.complexWordIdentification(this.postIWant, this.theHardWords);

The issue here is that this.postIWant and this.theHardWords are getting resolved in the ngOnInit itself as you can see below, which is causing the error. 这里的问题是this.postIWantthis.theHardWordsngOnInit本身得到解决,如下所示,这导致了错误。 Now how can I call the this.complexWordIdentification(this.postIWant, this.theHardWords); 现在我怎样才能调用this.complexWordIdentification(this.postIWant, this.theHardWords); and feed it those values without getting an error? 并提供这些值而不会出错?

I have been thinking about the await functions? 我一直在考虑等待功能吗? But I can not figure it out, any advice on this, please? 但我无法弄明白,对此有何建议,拜托?

This is my ngOnInit : 这是我的ngOnInit

ngOnInit() {
    this.isLoading = true;
    this.wordsLoaded = false;
    this.postLoaded = false;
    this.form = new FormGroup({
      annotation: new FormControl(null, {
        validators: [
          Validators.required,
          Validators.minLength(8),
          Validators.maxLength(250)
        ]
      })
    });
    this.id = this.route.snapshot.paramMap.get('postId');
    this.annotationService.getWords();
    this.annotationSub = this.annotationService
      .getWordUpdateListener()
      .subscribe((thewords: ComplexWord[]) => {
        this.thewords = thewords;
        this.thewords.map(word => {
          this.theHardWords.push(word.word);
          this.wordWithAnnotation.push(word);
        });
        this.wordsLoaded = true;
        this.isLoading = this.postLoaded && this.wordsLoaded;
      });
    this.postsService.getPosts();
    this.postsSub = this.postsService
      .getPostUpdateListener()
      .subscribe((posts: Post[]) => {
        this.posts = posts;
        this.posts.map(post => {
          if (post.id === this.id) {
            this.postIWant = post.fileText;
          }
        });
        this.postLoaded = true;
        this.isLoading = !(this.postLoaded && this.wordsLoaded);
      });
    this.role = this.authService.getUserRole();
    this.userIsAuthenticated = this.authService.getIsAuth();
    this.authStatus = this.authService
      .getAuthStatus()
      .subscribe(isAuthenticated => {
        this.userIsAuthenticated = isAuthenticated;
        this.role = this.authService.getUserRole();
      });
}

If anyone can point me in the right direction it would be great, as I am not too experienced in this field. 如果有人能指出我正确的方向,这将是伟大的,因为我在这个领域不太有经验。 Currently I am having to call this.complexWordIdentification(this.postIWant, this.theHardWords); 目前我不得不称之为this.complexWordIdentification(this.postIWant, this.theHardWords); outside of the ngOnInit to avoid the error but obviously, I would like to call it automatically. ngOnInit之外避免错误,但很明显,我想自动调用它。

forkJoin combines the two subscriptions into a single one and returns an array of their results. forkJoin将两个订阅组合成一个订阅并返回其结果数组。 It is extremely useful to use in ngOnInit when you need data from multiple sources before you can finish loading the component. 在完成加载组件之前,如果需要来自多个源的数据,则在ngOnInit使用非常有用。

https://www.learnrxjs.io/operators/combination/forkjoin.html https://www.learnrxjs.io/operators/combination/forkjoin.html

import { Observable } from "rxjs/Observable";
    Observable.forkJoin(
        this.annotationService.getWordUpdateListener(),
        this.postsService.getPostUpdateListener()
    ).subscribe((data) => {
         // data[0] result from getWordUpdateListener
         this.thewords = data[0];
            this.thewords.map(word => {
              this.theHardWords.push(word.word);
              this.wordWithAnnotation.push(word);
            });
            this.wordsLoaded = true;

         // data[1] result from getPostUpdateListener
         this.posts.map(post => {
              if (post.id === this.id) {
                this.postIWant = post.fileText;
              }
            });
            this.postLoaded = true;
        this.isLoading = false;
        this.complexWordIdentification(this.postIWant, this.theHardWords);
    }, (err) => {
        // error handling
    });

edit:added Import Statement for Observable in RXJS 5 and below 编辑:在RXJS 5及更低版本中添加了Observable的Import语句

Edit: RXJS 6 update, changes import statment 编辑:RXJS 6更新,更改导入语句

import { forkJoin} from 'rxjs';
forkJoin(this.annotationService.getWordUpdateListener(),
            this.postsService.getPostUpdateListener()
).subscribe((data) => { \\do stuff}, (err) => { \\ do error stuff}

Edit 2: RXJS changed the signature of forkJoin it now takes an array 编辑2:RXJS改变了forkJoin的签名,它现在需要一个数组

    forkJoin([this.annotationService.getWordUpdateListener(),
            this.postsService.getPostUpdateListener()]
).subscribe((data) => { \\do stuff}, (err) => { \\ do error stuff}

Because you need data from two separate streams at once you need to combine the streams in some way. 因为您需要同时从两个单独的流中获取数据,所以您需要以某种方式组合流。 Below is an example of how you could: 以下是您可以:

this.annotationService.getWordUpdateListener().pipe(
  switchMap(thewords => {
    return this.postsService.getPostUpdateListener().pipe(
      map(posts => ({ thewords, posts }))
    );
  }),
)
.subscribe(({ thewords, posts }) => {
  this.complexWordIdentification(posts, thewords);
});

If you need both this.postIWant, this.theHardWords always on component initialization you can probably use angular resolve ie https://angular.io/api/router/Resolve 如果你需要this.postIWant,this.theHardWords总是在组件初始化你可以使用角分辨率,即https://angular.io/api/router/Resolve

Example:- 例:-

class Backend {
  fetchTeam(id: string) {
    return 'someTeam';
  }
}

@Injectable()
class TeamResolver implements Resolve<Team> {
  constructor(private backend: Backend) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<any>|Promise<any>|any {
    return this.backend.fetchTeam(route.params.id);
  }
}

@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'team/:id',
        component: TeamCmp,
        resolve: {
          team: TeamResolver
        }
      }
    ])
  ],
  providers: [TeamResolver]
})
class AppModule {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM