JavaScript类属性赋值后仍返回undefined问题求助
问题分析与解决办法
你的问题核心是异步操作的执行时机。getAuthToken()是返回Promise的异步函数,构造函数里的then回调要等异步请求完成后才会执行,而你在File2里创建实例后立刻打印authToken,这时候异步请求还没结束,this.authToken自然还没被赋值,所以返回undefined。
下面是几种可行的解决办法:
方案1:添加异步初始化方法
把token的获取逻辑从构造函数移到独立的异步方法中,外部创建实例后先等待初始化完成:
File 1 修改后:
class Clazz { authToken; async init() { this.authToken = await getAuthToken(); } } const getAuthToken = () => { return new Promise((resolve, reject) => { adalcontext.acquireTokenWithClientCredentials(resourceapi, clientId, clientSecret, (error, tokenResponse) => { if (error) { reject(new Error(`Failed to authenticate: ${error.message}`)); } else { resolve(tokenResponse.accessToken); } }); }); };
File 2 修改后:
const clazz = new Clazz(); // 用自执行异步函数等待初始化完成 (async () => { await clazz.init(); console.log(clazz.authToken); // 此时能拿到正确的token值 })();
方案2:异步构造函数(注意实例需通过await获取)
如果想在构造阶段就完成token获取,可以用异步构造函数,但此时new Clazz()返回的是Promise,需要await才能拿到实例:
File 1 修改后:
class Clazz { authToken; constructor() { return (async () => { this.authToken = await getAuthToken(); return this; })(); } } const getAuthToken = () => { return new Promise((resolve, reject) => { adalcontext.acquireTokenWithClientCredentials(resourceapi, clientId, clientSecret, (error, tokenResponse) => { if (error) { reject(new Error(`Failed to authenticate: ${error.message}`)); } else { resolve(tokenResponse.accessToken); } }); }); };
File 2 修改后:
(async () => { const clazz = await new Clazz(); console.log(clazz.authToken); // 正确获取token })();
方案3:用getter返回Promise
给类添加getter方法,直接返回获取token的Promise,外部通过await拿到最终值,同时用私有字段避免外部直接访问未初始化的token:
File 1 修改后:
class Clazz { #authToken; // 私有字段,仅类内部可访问 constructor() { this.#authToken = getAuthToken(); } get authToken() { return this.#authToken; } } const getAuthToken = () => { return new Promise((resolve, reject) => { adalcontext.acquireTokenWithClientCredentials(resourceapi, clientId, clientSecret, (error, tokenResponse) => { if (error) { reject(new Error(`Failed to authenticate: ${error.message}`)); } else { resolve(tokenResponse.accessToken); } }); }); };
File 2 修改后:
const clazz = new Clazz(); (async () => { const token = await clazz.authToken; console.log(token); // 正确获取token })();
内容的提问来源于stack exchange,提问作者ineedhelp
相关产品推荐
相关产品推荐

