如何在查询块外部访问变量?Node.js异步数据库查询问题
问题原因与解决方案
问题本质
你遇到的空值问题核心是数据库查询的异步执行特性:db.all是异步方法,它的回调函数会在数据库查询完成后才执行,但你写在回调外面的for循环会在db.all调用后立刻执行——这时候currMarker还没被赋值,依然是空数组,所以循环不会输出任何内容。
解决方案
方案1:用Promise封装 + async/await(推荐)
把异步的数据库查询包装成Promise,再用async/await等待查询完成,之后就能正常遍历结果:
const sql = 'SELECT * FROM people'; let currMarker = []; // 将db.all封装为Promise function getPeople() { return new Promise((resolve, reject) => { db.all(sql, [], (err, rows) => { if (err) reject(err); else resolve(rows); }); }); } // 用async函数处理异步逻辑 async function fetchAndProcessData() { try { // 等待查询完成,再给currMarker赋值 currMarker = await getPeople(); // 现在可以正常遍历 for (let i = 0; i < currMarker.length; i++) { console.log(currMarker[i].name); console.log(currMarker[i].username); } } catch (err) { console.error(err.message); } } fetchAndProcessData();
方案2:抽离处理逻辑到函数,在回调中调用
如果不想用Promise,也可以把遍历逻辑抽成独立函数,在查询完成的回调里调用它:
const sql = 'SELECT * FROM people'; let currMarker = []; // 定义处理结果的函数 function printMarkers(markers) { for (let i = 0; i < markers.length; i++) { console.log(markers[i].name); console.log(markers[i].username); } } db.all(sql, [], (err, rows) => { if (err) return console.error(err.message); currMarker = rows; // 查询完成后调用处理函数 printMarkers(currMarker); });
关键说明
JavaScript中异步操作不会阻塞后续代码执行,所以必须确保遍历逻辑在异步操作完成后执行——上面两种方案都是通过不同方式实现了这一点,你可以根据自己的代码风格选择。
内容的提问来源于stack exchange,提问作者redfries
相关产品推荐
相关产品推荐

