可否扩展嵌套回调风格的类并用async/await编写子类?是否存在问题?
可以扩展,不存在本质兼容或运行层面的问题
回调风格的异步实现和async/await语法在底层是互通的,只要做一层Promise包装即可,不会影响原有遗留类的逻辑运行,具体实现和注意事项如下:
- 核心实现思路:先把父类的回调风格方法包装为返回Promise的方法,再在子类的async方法中直接await调用即可,示例代码如下:
// 原有回调风格的遗留父类 class LegacyCallbackClass { queryUser(userId, callback) { // 原有遗留逻辑,参数最后一位是错误优先的回调函数 setTimeout(() => { if (userId < 1) return callback(new Error('无效用户ID')) callback(null, { id: userId, name: 'testUser' }) }, 200) } } // 用async/await实现的子类 class AsyncSubClass extends LegacyCallbackClass { // 先封装父类回调方法为Promise版本 #queryUserPromise(userId) { return new Promise((resolve, reject) => { super.queryUser(userId, (err, result) => { if (err) return reject(err) resolve(result) }) }) } // 业务方法直接用async/await编写 async getUserInfo(userId) { try { const user = await this.#queryUserPromise(userId) // 后续自定义业务逻辑 user.createTime = new Date().toISOString() return user } catch (err) { console.error('查询用户失败', err) throw err } } }
- 仅需注意两个细节即可完全规避运行问题:
- 包装Promise时必须正确处理回调的错误参数,所有回调抛出的异常都要通过
reject()透出,否则await时会出现未捕获的Promise rejection报错 - 子类不要修改父类原有方法的入参、内部执行逻辑,仅做上层封装,原有遗留代码的逻辑完全保留,就不会出现兼容问题
- 包装Promise时必须正确处理回调的错误参数,所有回调抛出的异常都要通过
- 如果遗留类的回调方法较多,可以自己实现通用的promisify工具函数批量包装,Node.js环境可以直接调用内置的
util.promisify减少重复代码。
内容的提问来源于stack exchange,提问作者sam
相关产品推荐
相关产品推荐

