You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js异步函数内SQLite请求的异步处理与结果返回问题

解决SQLite异步查询导致返回空数组的问题

你碰到的问题本质是没抓住SQLite each()方法的异步特性——它会立刻返回,然后在后台逐步处理查询结果,而你的代码在结果还没遍历完的时候就急着返回数组了,自然拿到的是空值。下面针对你给出的两种方案分别修正,帮你理解怎么正确等待异步操作完成。

修正Promise方案

原来的代码里,你在each()调用后直接resolve(array),但这时候each()还没开始遍历结果呢!我们要利用each()的第三个参数——完成回调,这个回调会在所有行都处理完毕后触发,这时候才是resolve数组的正确时机。

修正后的dbHandler.js代码

var Promise = require("bluebird");
getList: function(userID) {
  return new Promise(function(resolve, reject) {
    var array = [];
    sql.each(
      `SELECT * FROM table WHERE userID = ?`,
      userID,
      // 每一行的处理回调
      (err, row) => {
        if (err) {
          // 遇到错误直接reject,终止后续处理
          return reject(err);
        }
        console.log("row: " + row + " element: " + row.username);
        array.push(row);
      },
      // 所有行处理完成的回调
      function(err, count) {
        if (err) {
          return reject(err);
        }
        // 现在数组已经被完全填充了
        console.log("array: " + JSON.stringify(array));
        resolve(array);
      }
    );
  });
}

修正后的list.js调用代码

db.getList(uid)
  .then(function(v) {
    // 注意:数组的长度是length,不是size!
    console.log("size: " + v.length);
    // 可以遍历验证结果
    v.forEach(element => console.log("element: " + element.username));
  })
  .catch(function(err) {
    console.log("failed: " + err);
  });

修正回调方案

回调方案的问题和Promise版本一样:你在each()还没处理完结果时就调用了自定义回调,这时候数组还是空的。同样要借助each()的完成回调来触发我们的自定义回调。

修正后的dbHandler.js代码

getList: function(userID, callback) {
  var array = [];
  sql.each(
    `SELECT * FROM warns WHERE userID = ?`,
    userID,
    // 每一行的处理回调
    (err, row) => {
      if (err) {
        // 出错时直接返回错误给回调
        return callback(err, null);
      }
      array.push(row);
    },
    // 所有行处理完成的回调
    function(err, count) {
      if (err) {
        return callback(err, null);
      }
      // 数组填充完毕,返回给调用方
      callback(null, array);
    }
  );
},

修正后的list.js调用代码

db.getList(uid, function (err, response) {
  if (err) {
    console.log("Error:", err);
  } else {
    // 同样用length获取数组长度
    console.log("size: " + response.length);
    response.forEach(element => console.log("element: " + element.username));
  }
});

关键要点总结

  • 等待异步操作完成:SQLite的each()是异步的,必须等到它的完成回调触发,才能确保所有结果都被加入数组。
  • 正确处理错误:不管是Promise的reject还是回调的错误参数,都要把错误传递出去,而不是只打印在控制台。
  • 数组属性小细节:数组的长度属性是length,不是size,这是你之前输出undefined的另一个原因。

内容的提问来源于stack exchange,提问作者omnomnom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:31:38