Angular 如何在继续下一行之前等待方法完成

Angular how to wait for method to finish before proceeding to next line

在组件内部,我试图调用一个方法 (getConfigSettings()),该方法又从服务(returns 一个可观察的集合)中调用另一个方法。

问题出在主要方法 (getConfigSettings()) 中,各行未按顺序执行。这意味着,不是等待可观察的调用完成,而是控制移动到下一行,

  localStorage.setItem('displayExpiryWarning', this.isEnabled ? JSON.stringify(false) : JSON.stringify(true));

this.isEnabled 属性 未设置。

代码示例:

export class ExamComponent implements OnDestroy, AfterViewInit {

    sub_modules: any;
    isEnabled: boolean = true;
    // .....
    // ......

    onStepA(): void {

            this.checkForCoverage();

    }



checkForCoverage(): void {

    this.getConfigSettings(); // This method never gets finished and control move to next line below        


    localStorage.setItem('displayExpiryWarning', this.isEnabled ? JSON.stringify(false) : JSON.stringify(true));

}



getConfigSettings() {
    this.sub_modules = this.ls.getProductModules().subscribe(
        (data) => {
            try {
                const dataXml = data.filter((data) => data.ModuleName == 'LoginModule')[0].XmlConfig;
                if (dataXml) {
                    const config = xmlToJson(dataXml);

                    this.isEnabled =
                        config['configuration'].appSettings.param.filter(
                            (data) => data.name == 'PropAEnabled',
                        )[0].value === 'true';            
                }                   


            } catch (e) {}
        },
        (err) => {},
    );
}  

}

您可以在 getConfigSettings() 下设置 localStorage 部分,或者 return Observable 来自 getConfigSettings() 并随时随地订阅。

如果您认为来自 Observable 的数据在后续的调用中不会改变 getConfigSettings() 那么你可以使用 shareReplay 并使 Observable 成为 class 属性.

checkForCoverage(): void {
    this.getConfigSettings().subscribe(() => {
        localStorage.setItem('displayExpiryWarning', this.isEnabled ? JSON.stringify(false) : JSON.stringify(true));
    });
}



getConfigSettings() {
    return this.ls.getProductModules().pipe(tap((data) => {
        try {
            const dataXml = data.filter((data) => data.ModuleName == 'LoginModule')[0].XmlConfig;
            if (dataXml) {
                const config = xmlToJson(dataXml);

                this.isEnabled =
                    config['configuration'].appSettings.param.filter(
                        (data) => data.name == 'PropAEnabled',
                    )[0].value === 'true';            
            }                   
        } catch (e) {}
    }));
}

您可以 return 来自 getConfigSettings() 的可观察对象并在 checkForCoverage() 函数中订阅它。尝试以下

checkForCoverage(): void {
  this.getConfigSettings().subscribe(
    response => {
      if (response) {
        localStorage.setItem('displayExpiryWarning', this.isEnabled ? JSON.stringify(false) : JSON.stringify(true));
      } else {
        // handle error
      }
    }
  );
}

getConfigSettings() {
  const result = new Subject<boolean>();

  this.sub_modules = this.ls.getProductModules().subscribe(
    data => {
      try {
        const dataXml = data.filter((data) => data.ModuleName == 'LoginModule')[0].XmlConfig;
        if (dataXml) {
          const config = xmlToJson(dataXml);
          this.isEnabled = config['configuration']
            .appSettings
            .param
            .filter((data) => data.name == 'PropAEnabled')[0]
            .value === 'true';
          result.next(true);      // <-- push `true` here
        }
      } catch (e) {
        result.next(false);       // <-- push `false` here
      }
    },
    err => {
      result.next(false);         // <-- push `false` here
    },
  );

  return result.asObservable();
}