You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 16调用login()后this.sid返回undefined问题求助

问题原因与解决方案

核心原因

HTTP请求是异步操作,this.http.post(...).subscribe(...)里的next回调要等请求成功返回后才会执行——也就是说this.sid的赋值逻辑是在请求完成后才触发的。而你在foo()里调用this.login()后立刻打印this.sid,这时候请求还在处理中,赋值操作根本没执行,所以会得到undefined。


解决方案

方案1:让login返回Observable,在foo中订阅等待结果

修改login函数,将HTTP请求的Observable返回出去,在foo里通过订阅来等待请求完成:

sid: string | undefined;

login() {
  const body = `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://www.ca.com/UnicenterServicePlus/ServiceDesk">
            <soapenv:Header/>
            <soapenv:Body>
                <ser:login>
                  <username>servicedesk</username>
                  <password>?</password>
                </ser:login>
            </soapenv:Body>
          </soapenv:Envelope>`;

  return this.http
    .post(this.soapURL, body, {
      headers: {
        'SOAPAction': "",
        'Content-Type': 'text/xml;charset=UTF-8'
      },
      responseType: 'text'
    })
    .pipe(
      map(res => {
        const parser = new xml2js.Parser({ strict: false, trim: true });
        let sid: string | undefined;
        parser.parseString(res, (err, result) => {
          this.soapenvEnvelope = result;
          sid = this.soapenvEnvelope?.["SOAPENV:ENVELOPE"]["SOAPENV:BODY"][0].LOGINRESPONSE[0].LOGINRETURN[0]._;
        });
        this.sid = sid;
        return sid;
      }),
      catchError(ex => {
        console.log(ex);
        throw ex;
      })
    );
}

foo() {
  this.login().subscribe({
    next: () => {
      console.log(this.sid); // 此时请求已完成,能拿到正确值
    },
    error: () => {}
  });
}

方案2:用async/await将login转为Promise

把Observable转为Promise,用同步风格的代码等待请求完成:

import { firstValueFrom } from 'rxjs'; // rxjs新版本推荐用这个替代toPromise

sid: string | undefined;

async login(): Promise<string | undefined> {
  const body = `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://www.ca.com/UnicenterServicePlus/ServiceDesk">
            <soapenv:Header/>
            <soapenv:Body>
                <ser:login>
                  <username>servicedesk</username>
                  <password>?</password>
                </ser:login>
            </soapenv:Body>
          </soapenv:Envelope>`;

  try {
    const res = await firstValueFrom(
      this.http.post(this.soapURL, body, {
        headers: {
          'SOAPAction': "",
          'Content-Type': 'text/xml;charset=UTF-8'
        },
        responseType: 'text'
      })
    );

    const parser = new xml2js.Parser({ strict: false, trim: true });
    let sid: string | undefined;
    parser.parseString(res, (err, result) => {
      this.soapenvEnvelope = result;
      sid = this.soapenvEnvelope?.["SOAPENV:ENVELOPE"]["SOAPENV:BODY"][0].LOGINRESPONSE[0].LOGINRETURN[0]._;
    });
    this.sid = sid;
    return sid;
  } catch (ex) {
    console.log(ex);
    throw ex;
  }
}

async foo() {
  await this.login();
  console.log(this.sid); // 等待请求完成后执行,能拿到正确值
}

内容的提问来源于stack exchange,提问作者elhanan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 11:13:15