如何重写/扩展JavaScript的await,实现自动加载屏功能?
解决await自动触发加载屏的方案
首先明确:await是JavaScript的语法关键字,无法直接重写它的行为,但我们可以通过封装工具函数或装饰器的方式,实现自动包裹加载逻辑的效果,彻底避免重复代码。
方案1:通用异步操作包装函数
封装一个工具方法,把需要执行的异步操作传入,方法内部自动处理加载的开启和关闭(无论操作成功/失败都会关闭加载)。
代码实现
// 在你的组件/类中定义这个方法 async withLoading<T>(asyncTask: () => Promise<T>): Promise<T> { this.startLoading(); try { // 执行传入的异步任务 return await asyncTask(); } finally { // 无论任务成功或失败,最终都会关闭加载 this.stopLoading(); } }
用法示例
替换fetch场景
// 原来的重复代码 // this.startLoading(); // await fetch('your-api-url'); // this.stopLoading(); // 现在的写法 await this.withLoading(() => fetch('your-api-url'));
替换RxJS的lastValueFrom场景
// 原来的重复代码 // this.startLoading(); // await lastValueFrom(this.http.get<Array<MiningRigDevice>>('/mining/devices')).then(res => this.miningRigDevices = res); // this.stopLoading(); // 现在的写法 const res = await this.withLoading(() => lastValueFrom(this.http.get<Array<MiningRigDevice>>('/mining/devices')) ); this.miningRigDevices = res;
方案2:类方法装饰器(适合Angular/类组件场景)
如果你的异步逻辑都封装在类的方法里,可以用装饰器给方法自动加上加载逻辑,彻底消除重复代码。
代码实现
// 定义装饰器函数 function Loading() { return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const originalMethod = descriptor.value; // 重写原方法,包裹加载逻辑 descriptor.value = async function(...args: any[]) { this.startLoading(); try { return await originalMethod.apply(this, args); } finally { this.stopLoading(); } }; return descriptor; }; }
用法示例
class YourComponent { miningRigDevices: Array<MiningRigDevice>; constructor(private http: HttpClient) {} // 给异步方法加上@Loading()装饰器 @Loading() async loadMiningDevices() { const res = await lastValueFrom(this.http.get<Array<MiningRigDevice>>('/mining/devices')); this.miningRigDevices = res; } @Loading() async fetchOtherData() { const response = await fetch('another-api-url'); const data = await response.json(); // 处理数据逻辑 } }
关键注意事项
- 上下文绑定:确保
this.startLoading()和this.stopLoading()中的this指向正确(工具函数中用箭头函数传入异步任务,或装饰器中用apply绑定原方法上下文,都能避免this指向问题)。 - 异常处理:用
finally块关闭加载,保证即使异步操作抛出错误,加载屏也会正常关闭,不会一直卡住。 - 通用性:两种方案都支持任意异步操作(Promise、Observable转Promise等),满足你“支持await后的任意操作”的需求。
内容的提问来源于stack exchange,提问作者Max Alexander Hanna
相关产品推荐
相关产品推荐

