在 ES6 类中,如果父类的属性是通过异步赋值的,子类能否获取到这个值取决于访问时机。下面通过代码示例详细说明:
1. 同步 vs 异步赋值的区别
同步赋值(正常情况)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Parent { constructor() { this.syncValue = '同步值'; } }
class Child extends Parent { getValues() { return { syncValue: this.syncValue }; } }
const child = new Child(); console.log(child.getValues());
|
异步赋值的情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Parent { constructor() { this.asyncValue = null; setTimeout(() => { this.asyncValue = '异步赋值完成'; }, 1000); } }
class Child extends Parent { getValues() { return { asyncValue: this.asyncValue }; } }
const child = new Child(); console.log(child.getValues());
setTimeout(() => { console.log(child.getValues()); }, 1500);
|
2. 解决方案
方案 1:使用 Promise 管理异步状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Parent { constructor() { this.asyncValue = null; this.valueReady = new Promise((resolve) => { setTimeout(() => { this.asyncValue = '异步赋值完成'; resolve(this.asyncValue); }, 1000); }); } }
class Child extends Parent { async getValues() { await this.valueReady; return { asyncValue: this.asyncValue }; } }
const child = new Child(); child.getValues().then(values => { console.log(values); });
|
方案 2:使用 async/await 模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Parent { constructor() { this.initialized = this.init(); }
async init() { this.asyncValue = await new Promise(resolve => { setTimeout(() => resolve('异步值'), 1000); }); }
async ensureInitialized() { await this.initialized; } }
class Child extends Parent { async getAsyncValue() { await this.ensureInitialized(); return this.asyncValue; } }
const child = new Child(); child.getAsyncValue().then(value => { console.log(value); });
|
方案 3:事件驱动模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| class Parent { constructor() { this.asyncValue = null; this.listeners = [];
setTimeout(() => { this.asyncValue = '异步值'; this.listeners.forEach(callback => callback(this.asyncValue)); }, 1000); }
onValueReady(callback) { if (this.asyncValue) { callback(this.asyncValue); } else { this.listeners.push(callback); } } }
class Child extends Parent { getValue(callback) { this.onValueReady(value => { callback(value); }); } }
const child = new Child(); child.getValue(value => { console.log(value); });
|
3. 实际应用场景
异步数据获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class ApiService { constructor() { this.userData = null; this.initialized = this.fetchUserData(); }
async fetchUserData() { this.userData = await fetch('/api/user').then(res => res.json()); }
async ensureReady() { await this.initialized; } }
class UserComponent extends ApiService { async getUserProfile() { await this.ensureReady(); return { name: this.userData.name, email: this.userData.email }; } }
|
总结
- 子类可以获取父类的异步赋值,但必须在异步操作完成后
- 立即访问可能得到
null 或初始值
- 推荐使用 Promise 或 async/await 来管理异步状态
- 通过等待初始化完成的方法确保数据可用性
- 事件监听模式适合需要实时响应的场景
关键在于时序控制 - 确保在访问异步值之前,相关的异步操作已经完成。