如何将Mongoose查询结果赋值到回调函数外的变量中?
解决Mongoose查询结果没法在回调外访问的问题
嘿,这个坑我之前也踩过!核心问题在于Mongoose的查询是异步操作——你现在的写法里,函数执行到末尾返回userObject的时候,findOne的回调还没触发呢,所以拿到的肯定是初始的空对象。要解决这个,得用异步代码的正确处理方式,给你两种实用方案:
方案一:用async/await(最推荐,代码最清爽)
把你的login_user改成异步函数,直接等待查询结果就行,不用嵌套回调:
async login_user(username, psw) { let hashedPsw = _SECURITY.string_to_sha1(psw); try { // 等着查询完成,直接拿到结果 const ret = await webkbuser.findOne({'user_username': username}).exec(); if (!ret) { // 用户不存在的情况,按需返回 return null; } // 这里做密码校验啥的后续操作 if (ret.user_password === hashedPsw) { // 校验过了,直接返回用户对象 return ret; } else { // 密码错了 return false; } } catch (err) { // 处理查询出错的情况 console.error('查用户的时候出错了:', err); throw err; // 或者返回错误信息,看你需求 } }
调用这个函数的时候,得用await(在异步函数里)或者.then():
// 举个调用的例子,得在异步函数里用await async function handleLogin() { const user = await login_user('你的用户名', '你的密码'); if (user) { console.log('登录成功!用户信息:', user); } else { console.log('用户名或密码错啦'); } }
方案二:用Promise链式调用
要是你暂时不想用async/await,用Promise的链式调用也能解决:
login_user(username, psw) { let hashedPsw = _SECURITY.string_to_sha1(psw); // 返回Promise,这样调用方可以后续处理 return webkbuser.findOne({'user_username': username}).exec() .then(ret => { if (!ret) { return null; } if (ret.user_password === hashedPsw) { return ret; } else { return false; } }) .catch(err => { console.error('查询用户失败:', err); throw err; }); }
调用的时候这么写:
login_user('你的用户名', '你的密码') .then(user => { if (user) { console.log('登录成功:', user); } else { console.log('登录失败'); } }) .catch(err => { console.error('登录过程出错:', err); });
为啥直接赋值外层变量不行?
简单说就是JavaScript的异步执行顺序:当你调用findOne().exec()时,这个查询会被放到“异步任务队列”里排队,函数会先跑完后面的代码(比如直接返回userObject),等主线程有空了才会执行回调里的赋值操作。这时候函数都已经返回了,userObject当然还是空的啦。
内容的提问来源于stack exchange,提问作者NashPL
相关产品推荐
相关产品推荐

