ngOnInit在APP_INITIALIZER完成之前开始

时间:2019-08-15 21:35:35

标签: angular

APP_INITIALIZER运行一系列嵌套的Promise(我尝试了订阅,结果没有差异)。

APP_INITIALIZER需要先通过身份验证,然后才能从API服务器检索数据。它还需要从API服务器中拉出两个表(按顺序)。

在api.service中,http / get授权发生在promise中。在答应之后(然后),我去从API服务获取数据。

问题出在组件ngOnInit()上,它试图在变量存在之前获取它们。

我已经在组件中尝试了以下代码,但是所做的只是两次调用initData()。

this.people = await this.apiService.initData();

api.service:

async initData(): Promise<Person[]> {
        this.userData$ = this.http.get('/.auth/me', {observe: 'response'});
        this.userData$.toPromise().then( res => {
          this.resBody = res.body;
          this.token = res.body[0].access_token;
          this.getLegalSub(this.legalsubdeptsURL)
            .toPromise().then(legalsubdepts => {
              this.legalsubdepts = legalsubdepts;
              this.getPeopleData(this.personURL)
              .toPromise().then(people => {
                this.people = people;
                return this.people;
              });
            });
        });
      }
      return this.people;
    }

app.module

export function initData(appInitService: APIService) {
  return (): Promise<any> => { 
    return appInitService.initData();
  }
}
...
providers: [
    APIService,
    { provide: APP_INITIALIZER, useFactory: initData, deps: [APIService], multi: true }
  ],

在APP_INITIALIZER完成之前运行的组件

ngOnInit() {
    this.people = this.apiService.people;
    this.userName = this.apiService.userName;
      console.log("username");
      console.log(this.userName);
  }

我必须先获得授权,然后才能从API服务器获取数据。 然后,在处理组件之前,我需要来自API服务器的数据。

最终我得到了数据,但没有及时获取组件。

2 个答案:

答案 0 :(得分:2)

APP_INITIALIZER是在初始化应用之前调用的回调。所有注册的初始值设定项都可以有选择地返回Promise。在启动应用程序之前,必须解决所有返回Promises的初始化函数。

在您的情况下,您返回一个诺言,但它几乎立即解决,因为您不等待响应完成。您应该等待您的承诺,并且可以通过await指令

来完成此操作
async initData(): Promise<Person[]> {
        this.userData$ = this.http.get('/.auth/me', {observe: 'response'});
        await this.userData$.toPromise().then(async res => {
          this.resBody = res.body;
          this.token = res.body[0].access_token;
          return await this.getLegalSub(this.legalsubdeptsURL)
            .toPromise().then(async legalsubdepts => {
              this.legalsubdepts = legalsubdepts;
              return await this.getPeopleData(this.personURL)
              .toPromise().then(people => {
                this.people = people;
                return this.people;
              });
            });
        });
      }
      return this.people;
    }

答案 1 :(得分:0)

答案:

api.service中的

-initData()需要返回Promise。代码进行得太远了。

initAuth(): Promise<any> {
    this.userData$ = this.http.get('/.auth/me', {observe: 'response'});
    return this.userData$.toPromise()
}

initLegalSub(): Promise<any[]> {
   this.initAuth().then( res => {
       this.resBody = res.body;
       this.legalSub$ =  this.getLegalSub(this.legalsubdeptsURL).toPromise();
   });
   return this.legalSub$;
}

initPeople(): Promise<Person[]> {
    this.initAuth().then( res => {
        this.resBody = res.body;
        this.people$ = this.getPeopleData(this.personURL).toPromise();
    });
    return this.people$;
}

您会注意到initLegalSub()和initPeople()都调用initAuth()-在尝试获取数据之前进行身份验证。

然后,这两个都返回Promise数据-用于people.component中。

constructor( private apiService: APIService ) { 
    this.legalSub$ = this.apiService.initLegalSub();
    this.people$ = this.apiService.initPeople();
  }

数据初始化在app.module中进行

providers: [
    APIService,
    { provide: APP_INITIALIZER, useFactory: initPeople, deps: [APIService], multi: true },
    { provide: APP_INITIALIZER, useFactory: initLegalSub, deps: [APIService], multi: true }],

如果应许失败,我应该投入更多的逻辑来确定该怎么做,但是目前,这允许多个初始化程序异步发生。