Node.js中.then()内赋值变量在函数外部访问异常如何解决
问题原因
该现象是JavaScript异步执行机制导致的,并非赋值逻辑错误。l.kategoriler.findAll()是异步数据库查询方法,返回Promise对象,传入.then()的回调不会立即执行,会被加入任务队列等待:只有同步代码全部执行完毕、数据库查询返回结果后,回调里的数组赋值逻辑才会运行。
写在.then()外部的console.log(arr)是同步代码,执行时查询还未完成,赋值逻辑尚未触发,因此拿到的始终是初始声明的空数组。
解决方法
方法1:所有依赖arr的逻辑全部放到.then回调内执行
这是Promise原生支持的写法,无额外语法兼容要求:
l.kategoriler.findAll({where:{server_id: "991656640401113118"}}).then(a =>{ // 直接用map生成目标数组,不需要提前声明空数组再循环push const arr = a.map(b => b.kategori) console.log(arr) // 所有需要用到arr的逻辑,包括数据渲染、参数传递、后续计算,全部写在这个回调作用域内 })
方法2:用async/await改写为类同步写法
该写法逻辑更贴近线性思维,注意await必须在被async标记的函数内使用(Node.js 14.8+、现代浏览器ES模块环境支持顶层await):
const fetchKategoriList = async () => { const queryResult = await l.kategoriler.findAll({where:{server_id: "991656640401113118"}}) const arr = queryResult.map(b => b.kategori) console.log(arr) // 此处可拿到正确赋值的数组 return arr } // 调用异步函数拿到结果后执行后续逻辑 fetchKategoriList().then(arr => { // 后续使用arr的业务逻辑 })
避坑提醒
- 不要用
setTimeout设置固定延时等待异步结果,查询耗时受网络、数据库负载影响不固定,这种写法稳定性极差。 - 不要强行把异步查询改为同步阻塞模式,会卡住整个JS运行线程,导致页面卡顿、服务响应阻塞。
- 原写法里提前声明空数组再遍历
push的操作是冗余的,Array.map本身会返回组装好的新数组,直接接收返回值即可。
内容的提问来源于stack exchange,提问作者Efe Dikyamaç
相关产品推荐
相关产品推荐

