JS类实例属性赋值后变回null?Node.js异步问题排查
问题根因
核心问题是静态new方法中调用异步的save()方法时没有加await,属于典型的异步流程未同步等待的问题。save()是async标记的异步方法,内部包含数据库连接、SQL执行等异步逻辑,不加await直接调用时,代码会立刻执行后续的return mymodel,把还没完成持久化的实例返回给控制器。此时save()方法内的数据库查询、_id赋值逻辑还在事件队列中未执行,控制器拿到实例调用toString()时,_id自然还是初始值null。
你调试时观察到save内部_id赋值成功,是因为断点阻塞了执行流程,实际运行时没有等待异步逻辑的话,赋值动作晚于实例返回、响应发送的时机,所以最终返回的内容里拿不到正确的id。
另外你静态方法标注的返回值类型是Promise<GekModel>,属于笔误,需要和实际返回的MyModel类型保持一致,避免TS类型推导出现异常。
修复代码
直接修改静态new方法,给save()调用加上await,确保所有持久化逻辑、属性赋值完成后再返回实例:
public static async new(name: string) : Promise<MyModel> { if (name === undefined || name === null || (name = name.trim()) === '') { name = uniqueNamesGenerator(); } const mymodel = new MyModel(name); await mymodel.save(); // 等待save逻辑全部执行完成 return mymodel; }
补充排查项
如果修改后问题仍然存在,依次检查以下点:
- 检查
save()方法的catch/finally块,确认没有吞掉数据库查询抛出的错误,避免查询失败时无感知,_id根本没有走到赋值分支 - 检查自定义的
toString()方法实现,确认读取的是实例上的_id属性,没有变量名拼写错误、或者读取了其他未赋值的冗余字段 - 确认
save()方法内拿到的result.rows[0][0]确实是正确的id值,没有出现字段顺序错位导致赋值为空的情况
内容的提问来源于stack exchange,提问作者Lon B
相关产品推荐
相关产品推荐

