我在Node.js中有一个代码,它从SQLite数据库中选择所有内容并打印每一行并且它可以工作,这里是代码:
var sqlite3=require('sqlite3').verbose();
var db=new sqlite3.Database('./database.db',(err)=>{
if(err){
return console.error(err.message);
}
console.log('Connected...');
});
db.all('SELECT * FROM langs ORDER BY name',[],(err,rows)=>{
if(err){
return console.error(err.message);
}
rows.forEach((row)=>{
console.log(row.name);
});
});
db.close((err) => {
if (err) {
return console.error(err.message);
}
console.log('Database closed...');
});
打印:
Connected...
C
Java
Database closed...
但是当我尝试使用它来将行放入数组时,它不起作用:
var data=[];
db.all('SELECT * FROM langs ORDER BY name',[],(err,rows)=>{
if(err){
return console.error(err.message);
}
rows.forEach((row)=>{
data.push(row);
});
});
for(col in data){
console.log(col.name);
}
打印:
Connected...
Database closed...
解决方案:修改代码以使用async/await
并将节点更新到版本8.11.1后,它可以运行,代码:
var data=[],records=[];
function getRecords(){
return new Promise(resolve=>{
db.all('SELECT * FROM langs ORDER BY name',[],(err,rows)=>{
if(err){
return console.error(err.message);
}
rows.forEach((row)=>{
data.push(row);
});
resolve(data);
});
});
}
async function asyncCall(){
records=await getRecords();
records.forEach(e=>{
console.log(e.name);
});
}
asyncCall();
答案 0 :(得分:1)
这是因为db.all
是asynchronous
。数据数组尚未填充,您正在尝试循环它。只需将for
循环移到里面就可以了。
您的最终代码应该是
var data=[],
records = [];
function getRecords(){
return new Promise((resolve,reject)=>{
db.all('SELECT * FROM langs ORDER BY name',[],(err,rows)=>{
if(err){
return console.error(err.message);
}
rows.forEach((row)=>{
data.push(row);
});
resolve(data);
})
})
}
(async function(){
records = await getRecords();
})()
PS。使用for(..in..)
并不是最好使用forEach