Node.js业务处理流程中complaintId变量意外重置问题求助
问题原因
核心是变量遮蔽(Variable Shadowing)+ 暂时性死区(TDZ) 导致的逻辑异常:
- 你在函数作用域顶部声明了第一个
complaintId变量,存储从请求参数拿到的ID,此时取值正常。 - 进入
if (counter == null)代码块后,你在解构语句中使用const {..., _id: complaintId} = complaint,相当于在当前if块的块级作用域内,重新声明了一个同名的complaintId变量。 - 由于
const声明的变量存在暂时性死区规则:在当前块级作用域内,从块开始的位置到变量声明语句的位置之间,访问该变量都会取到未初始化的undefined值,此时外层同名变量已经被块内变量遮蔽,不会被访问到。 - 因此你在if块开头打印的
complaintId实际上是块内还没完成赋值的新变量,自然是undefined,后续用这个undefined查询数据库也自然返回空结果。
修复方案
把解构时的变量名改为不和外层冲突的名称即可,示例修改:
const complaintById = ComplaintTC.mongooseResolvers.findById().wrapResolve(next => async rp => { const complaintId = rp.args._id logger.debug("rp.args ", complaintId) let counter = await ComplaintVisitCount.findOne({complaintId}) logger.debug("found counter by cid: ", complaintId, ": ", counter) if( counter == null ) { logger.debug("finding complaint by id: ", complaintId) const complaint = await Complaint.findById(complaintId) logger.debug("found complaint by id: ", complaintId, ": ", complaint) // 修改变量名避免冲突 const {entityGroupId, entityId, _id: targetComplaintId} = complaint counter = {entityGroupId, entityId, complaintId: targetComplaintId, visits:1} ComplaintVisitCount.create(counter) } else { counter.visits++ await counter.save() } const toReturn = await next(rp); toReturn.stats.visits = counter.visits logger.debug("returning complaint with ", counter.visits, " visits: ", toReturn ) return toReturn })
额外建议:增加complaint为空的判断,避免解构null/undefined抛出TypeError异常:
const complaint = await Complaint.findById(complaintId) if (!complaint) { throw new Error('对应投诉记录不存在') }
内容的提问来源于stack exchange,提问作者Zied Hamdi
相关产品推荐
相关产品推荐

