使用 push 将 JS 对象插入数组在某些上下文中不起作用

Using push for inserting JS object into an array wont work at certain context

在下面的代码中,在“db.each”中使用的 users.push 将不起作用。但是,如果我将“users.push”移到外面,它似乎就可以工作了。

如何将 db.each 中的新对象推送到用户数组中?

let db = new sqlite3.Database('./db/main.db', (err) => {
  if (err) console.error(err.message);
  console.log('Connected to the main database.');
});

var users = [];

db.serialize(() => {
  db.each(`SELECT email, name FROM users`, (err, row) => {
    if (err) console.error(err.message);
    let user = {
      email: row.email,
      name: row.name
    }
    users.push(user);
  });
});

console.log(JSON.stringify(users));
db.close();

我正在使用 express 和 sqlite3 节点包。

因为db.serializedb.each是异步函数(而return是立即执行的,所以在db回调执行之前执行console.log

这里应该是一个工作示例:

db.serialize(() => {
      db.each(`SELECT email,
                      name
               FROM users`, (err, row) => {
        if (err) {
          console.error(err.message);
        }

        let user = {
            email : row.email,
            name : row.name
        }

        users.push(user);

        console.log(JSON.stringify(users));

        db.close(); 

      });
    });

第一个错误:异步处理不当

正如 Antoine Chalifour 指出的那样,在异步回调中修改 users 之前调用 console.log(JSON.stringify(users));。请参阅他的回答以获取修复和解释。

第二个错误:未处理的错误

您编写了 if (err) { console.error(err.message); },然后继续完成该函数的其余部分。这很糟糕,因为可能会发生错误,而您只需继续您的程序即可。你应该这样写:

if (err) {
  console.error(err);
  return;
}

或:

if (err) throw err;