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
相关产品推荐
相关产品推荐

