Angular/rxJs concatMap - 进行两次网络 api (http) 调用,要么不完成,要么控制移动到后续行

Angular/rxJs concatMap - making two web api (http) calls, either dont finish and control move to subsequent lines

我正在尝试在我的 angular 9 应用程序中使用 rxJs concatMap。基本上我需要使用 http 进行两次 Web api 调用,两者都是 return 可观察值,填充其他值。第一次调用需要 return 一些值,这些值将用作第二次 api 调用的参数,然后应该继续。我尝试使用 tap 为此使用 concatMap,但没有成功。当调用方法(checkForRenewal())时,第一行被命中,但等待 api 调用完成或转到第二个 api 调用,它移动到其他行。

程序要么没有等待第一个完成,要么第二个调用没有正确执行,并且控件移至下一行(在 2 个网络 api 调用之后)。几秒钟后,我看到第一个 API 被触发并读取了值,但为时已晚。

我在 contactMap 之后还有其他 api 个电话...但不包括此 post。

如何实现这个或者有什么问题?我需要在 concatMap 之后进行最终订阅吗?下面的示例代码。

 checkForRenewal(): void {

 this.ls.getSoftwareModules()  //first web api call
        .pipe(         
            tap((data) => {                  
                {
                    try {
                        const dataXml = data.filter((data) => data.SoftwareModuleName == 'Activation')[0].XmlConfig;
                        if (dataXml) {
                            const config = xmlToJson(dataXml);
                            this.autoRenewalEnabled =
                                config['configuration'].appSettings.param.filter(
                                    (data) => data.name == 'AutoRenewalEnabled',
                                )[0].value === 'true';


                            this.autoRenewalCheckingFrequencyInHours = config[
                                'configuration'
                            ].appSettings.param.filter(
                                (data) => data.name === 'AutoRenewalCheckingFrequencyInHours',   //this line not hitting first, but later gets hit
                            )[0].value;

                        }
                    } catch (e) {

                    }
                }
            }),
            concatMap(() => this.ls.checkForRenewalAlreadyRan(this.autoRenewalCheckingFrequencyInHours, true)),  //2nd web api call
            tap((data2) => {
                this.skipKeyRenewal = data2;
                console.log('checkForRenewalAlreadyRan-->' + data2);
            }),
        )
        .subscribe((resp) => {
            console.log(resp);
        });

    if (this.skipKeyRenewal) {   //issue ...control seem to reach here first before making the above  api calls using concatMap
        console.log('auto renewal program already ran in last 24 hours, so processing will not resume!');
        return;
    } else {
        console.log('process continue for auto renewal...');
    }



 this._activationService.getActivationSites().subscribe({
        next: (resp) => {
            this.sites = resp;
            this.siteName = this.sites[0].SiteName;
            this.siteID = this.sites[0].SiteID;
        },
        error: (err) => {
            console.log(`err-->${err}`);
        },
    });

    this._activationService.getUuidPartial().subscribe({
        next: (resp) => {
            this.hardwareID = resp;
            this.decimalHardwareID = parseInt(this.hardwareID, 16);
        },
        error: (err) => {
            console.log(`err-->${err}`);
        },
    });

    hData = this._activationService.getProductActivations('ProductA', this.showKeys);   
    gData = this._activationService.getProductActivations('ProductB', this.showKeys);

    //other stuff goes here on wards


    ==============================================

    //two api calls returning observables in service ( lookup.service.ts)

//1st web api   
getSoftwareModules(where: string = '', orderBy: string = ''): Observable<SoftwareModule[]> {
    const url = `${this.config.host}${GLOBAL.SV_GET_MODULE_LIST}sessionID=${this.appSession.session.SessionID}&where=${where}&orderby=${orderBy}`;
    return this.http.get<SoftwareModule[]>(url);
}


//2nd web api 
checkForRenewalAlreadyRan(frequencyInHoures: number, isApiReady: boolean): Observable<boolean> {
    const url = `${this.config.host}${GLOBAL.SV_GET_KEY_RENEWAL_SETTINGS}sessionID=${this.appSession.session.SessionID}&frequencyInHoures=${frequencyInHoures}&isApiReady=${isApiReady}`;       
     return this.http.get<boolean>(url);      
}

我看到三个成员变量 this.autoRenewalEnabledthis.autoRenewalCheckingFrequencyInHoursthis.skipKeyRenewal 在异步调用中被赋值。这些变量被异步赋值。因此,当您尝试在订阅之外访问它时,它们可能尚未分配值。在尝试访问订阅之外的 this.skipKeyRenewal 时可以看到该问题。它实际上应该在订阅内

this.ls.getSoftwareModules()
  .pipe(
    ...
  )
  .subscribe((resp) => {
    console.log(resp);
    if (this.skipKeyRenewal) {   //issue ...control seem to reach here first before making the above  api calls using concatMap
      console.log('auto renewal program already ran in last 24 hours, so processing will not resume!');
      return;
    } else {
      console.log('process continue for auto renewal...');
    }
  });

同样,依赖于这三个变量中任何一个的所有代码都必须在订阅内。