在JavaScript/NodeJs类中调用同类方法报错问题排查
问题解决:TypeError: Cannot read property 'listTests' of undefined
错误原因
你在listOrgTests方法里创建Promise时用了普通函数作为回调:
return new Promise(async function(resolve, reject) { ... })
普通函数会生成独立的this上下文,这里的this并不指向TestDB类的实例,在严格模式下会直接变成undefined,所以调用this.listTests必然报错。
修复方案(推荐箭头函数)
把Promise的回调换成箭头函数——箭头函数不会绑定自身的this,会直接继承外层作用域的this(也就是当前TestDB类的实例):
修改后的listOrgTests方法:
async listOrgTests(orgID) { console.log('/listOrgTests: ', orgID); const ts = this.TestClass; var ta = new Array(); return new Promise(async (resolve, reject) => { // 替换为箭头函数 const sql = ` SELECT * FROM tests WHERE org_id = ? ORDER BY test_cdate DESC `; try { ta = await this.listTests(sql, orgID); return resolve(ta); } catch (err) { console.error("TestDB.listOrgTests: Error: ", err); return reject(err); // 需传入错误对象,否则无法捕获具体报错信息 } }) }
额外优化建议
你写的listTests方法存在不必要的Promise嵌套,且async函数本身会返回Promise,可以直接把dbc.query包装成Promise,简化代码结构:
优化后的listTests方法:
async listTests(sql, id) { console.log('/listTests: ', id); const dbc = this.dbc; const ts = this.TestClass; // 将dbc.query转换为Promise形式,避免嵌套 const row = await new Promise((resolve, reject) => { dbc.query(sql, [id], function(err, row) { if (err) return reject(err); resolve(row); }); }); console.log("TestDB.listTests: Queried ID: " + id + " " + row.length + " rows"); const ta = []; for (var i = 0; i < row.length; i++) { // 处理数据逻辑 } console.log('returned test array: ', ta); return ta; }
这样代码更简洁清晰,也符合async/await的最佳实践,避免了嵌套Promise带来的错误处理混乱。
内容的提问来源于stack exchange,提问作者TenG
相关产品推荐
相关产品推荐

