【问题标题】:angular waiting for a method to finish or a variable to be initialized等待方法完成或变量被初始化的角度
【发布时间】:2018-07-05 05:53:00
【问题描述】:

我有一个用作本地数据存储的服务,用于在应用程序之间共享数据。 该服务在开始时会进行一些休息调用以初始化一些数据。它看起来像这样:

Injectable()
export class DataStoreService {
     leadList: LeadModel[]
     optyList: ContactModel[]

     constructor(public dataService:DataService){
         this.initializeData()
     }

     initializeData() {

         this.dataService.getObjectData('opportunities').subscribe(
             (data) =>  this.optyList = data
         )

         this.dataService.getObjectData('leads').subscribe(
             (data) =>  this.leadList = data
         )
     }
}

我有一个组件页面,我在下面做:

ngOnInit() {
     for(let lead of this.dataStore.leadList){
             if(lead.accepted == false)
              this.newLeadsList.push(lead)
     }
}

很明显,如果初始化数据未能完成,leadList 可能是未定义的,这个 ngOnInit for 循环也会崩溃。那么,如何在 ngOnInit 中等待直到 initializeData 完成?

【问题讨论】:

标签: javascript angular typescript promise


【解决方案1】:

从构造函数中删除 initializeData() 并执行以下操作:

public async initializeData()
{
   this.optyList = await this.dataService.getObjectData('opportunities').toPromise();
   this.leadList = await this.dataService.getObjectData('leads').toPromise();
}


async ngOnInit() 
{
     await initializeData();

     for(let lead of this.dataStore.leadList){
         if(lead.accepted == false)
         this.newLeadsList.push(lead)
     }  
}  

我从头部编写代码,因此它可能有一些错误 - 可能是异步也应该在函数 ngOnInit() 之前...检查这个。

Async-await-toPromise 使您的异步函数表现为同步函数...并且 JS 等到您的 toPromise 完成后再执行另一个承诺...

更新

如果我的理解正确:您想调用一次您的服务“DataStoreService.initializeData()”并在未来在其他组件中使用它(无需再次调用 initializeData) - ? - 如果是,那么您需要 Service singleton(也可以在上面的 async-await 技术中使用)

【讨论】:

  • 我认为在我的应用程序的所有页面中调用 initializeData() 不是一个好的选择。可能有页面显示不同的数据。
  • 我不明白 - 为什么你说你想要(或不想)在所有页面中调用 initializeData?
  • 好吧,如果我说 20 页。我不想在所有页面的 ngInit 中执行 initializeData()。我想要的是我可以调用 this.data.leadList 如果它没有被初始化那么我的代码可以在那里等待
  • 我是否理解正确:您想调用您的服务 DataStoreService。 initializeData() 一次并在将来在其他组件中使用它(无需调用 initializeData) - ? - 如果是,那么你需要服务单例stackoverflow.com/q/36198785/860099
  • for 循环必须在initializeData() 解析后调用。检查这个repl.it/repls/MediumorchidMixedCatfish
【解决方案2】:

您可以使用 observables,在这种情况下,您订阅了 BehaviorSubject,如果有订阅者,则始终发出。发出初始请求后,只需调用next,所有订阅的组件都将获得该值......当它最终到达时:

数据存储服务:

import {BehaviorSubject} from 'rxjs/BehaviorSubject';

// ...

leadList: LeadModel[]
leadList$ = new BehaviorSubject<LeadModel[]>([])

constructor(public dataService:DataService){
  this.initializeData()
}

initializeData() {
  this.dataService.getObjectData('leads')
    .subscribe((data) =>  {
      this.leadList = data;
      this.leadList$.next(this.leadList)
    })
}

然后在你的组件中,订阅leadList$

leadList = <LeadModel[]>[];

ngOnInit() {
  this.dataStore.leadList$.subscribe(data => {
    this.leadList = data;
    // do your magic here :)
  })
}

然后记得在组件销毁时取消订阅!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    • 2019-01-31
    相关资源
    最近更新 更多