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

Node.js新手求助:使用回调获取MongoDB查询结果失败

解决MongoDB数据获取异步问题的方案

别担心,新手遇到异步问题太正常啦!你的核心问题是Node.js里MongoDB的操作是异步的,但你的list函数是同步返回数组,所以当你调用list()的时候,数据库查询还没完成,自然拿不到预期的数据。

先拆解你的代码问题点:

var list=()=>{ 
  var arr=[] 
  var blQ={blocked_user:data.tag_search_mail} 
  db.collection("block_list").find(blQ,{"_id":0}).toArray((err,res)=>{ 
    for(let i=0;i<res.length;i++){ 
      arr.push(res[i]["blocker"]) 
    } 
  }); 
  return arr // 这里会直接返回空数组,因为toArray的回调还没执行!
}

toArray是异步函数,它的回调会在数据库查询完成后才触发,但你的list函数不等这个回调结束,直接就返回了空的arr,这就是你拿不到数据的原因。

下面给你三种从简单到现代的解决方案:

方法1:用回调函数传递结果

把后续要执行的逻辑(比如你的showList)作为回调传给list,让异步操作完成后再调用:

var list=(callback)=>{ 
  var blQ={blocked_user:data.tag_search_mail} 
  db.collection("block_list").find(blQ,{"_id":0}).toArray((err,res)=>{ 
    if(err) return callback(err); // 别忘了处理错误
    var arr = []
    for(let i=0;i<res.length;i++){ 
      arr.push(res[i]["blocker"]) 
    } 
    callback(null, arr); // 查询完成后把数组传给回调
  }); 
}

// 调用的时候
list((err, resultArr) => {
  if(err) {
    console.error("查询出错:", err);
    return;
  }
  console.log("拿到的数据:", resultArr);
  // 在这里调用你的showList函数
  showList(resultArr);
});

方法2:用Promise封装异步操作

用Promise把数据库查询包起来,这样可以用.then()链式处理结果,代码结构更清晰:

var list=()=>{ 
  return new Promise((resolve, reject) => {
    var blQ={blocked_user:data.tag_search_mail} 
    db.collection("block_list").find(blQ,{"_id":0}).toArray((err,res)=>{ 
      if(err) return reject(err);
      // 用map替代for循环,代码更简洁
      var arr = res.map(item => item["blocker"]);
      resolve(arr);
    }); 
  });
}

// 调用的时候
list()
  .then(resultArr => {
    console.log("拿到的数据:", resultArr);
    showList(resultArr);
  })
  .catch(err => {
    console.error("查询出错:", err);
  });

方法3:用async/await(最推荐,代码像同步一样好读)

这是现代Node.js最常用的写法,让异步代码看起来和同步逻辑一致:

// 把list改成async函数
var list=async()=>{ 
  var blQ={blocked_user:data.tag_search_mail} 
  // await会等待数据库查询完成(新版MongoDB驱动的toArray本身返回Promise)
  var res = await db.collection("block_list").find(blQ,{"_id":0}).toArray();
  var arr = res.map(item => item["blocker"]);
  return arr;
}

// 调用时需要在async函数里用await
async function run() {
  try {
    var resultArr = await list();
    console.log("拿到的数据:", resultArr);
    showList(resultArr);
  } catch(err) {
    console.error("查询出错:", err);
  }
}

run();

最后提两个小细节:

  • 别直接throw err,生产环境里建议用更友好的错误处理逻辑
  • 新版MongoDB驱动(v4+)里,MongoClient.connect也支持Promise/async/await,你可以把数据库连接逻辑也改成异步的,避免多层回调嵌套

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:31:00