如何让Mongoose Promise立即解析以同步使用其值?
问题:如何让MongoDB的countDocuments Promise立即解析以同步使用结果?
我需要在代码中执行const voters = Player.countDocuments({})这个Promise语句,让它立即解析出结果,这样后续代码就能直接使用这个值。我试过拆分函数、调整Socket位置、用async/await、.resolve().then()等方法,但结果总是在我需要用到计票数值之后才解析出来。
初始代码示例:
io.on('connection', (socket) => { socket.on('direction vote', (individualVote) => { var voteCount = 1; var yesVotes = 1; // 统计游戏中的玩家数量 const voters = Player.countDocuments({}) .then((voterCount) =>{console.log('voterCount: ' + voterCount);}); // 接收并统计投票 if (individualVote == 'yes') { yesVotes ++; voteCount ++; console.log('yesVotes: ' + yesVotes); }; console.log('voters: ' + voters); // 这里输出的是Promise对象 if (voteCount == voters) { // 执行后续逻辑 // 向所有人发送投票结果 io.emit('direction vote result', voteResult); }; }); });
补充:我之前尝试的async/await写法(错误示范)
io.on('connection', (socket) => { socket.on('direction vote', (individualVote) => { var voteCount = 1; var yesVotes = 1; // 统计游戏中的玩家数量 async function count() { const countVoters = await Player.countDocuments({}); console.log('countVoters: ' + countVoters); return countVoters; } var voters = count(); console.log('voters: ' + voters); // 接收并统计投票 if (individualVote == 'yes') { yesVotes ++; voteCount ++; console.log('yesVotes: ' + yesVotes); }; console.log('voters: ' + voters); // 依然输出Promise对象 if (voteCount == voters) { // 执行后续逻辑 // 向所有人发送投票结果 io.emit('direction vote result', voteResult); }; }); });
解决方案
首先明确:Promise本质是异步的,无法真正转换成同步代码,但可以通过async/await让代码写法上接近同步逻辑。你之前的错误在于没有正确使用await等待Promise解析,导致后续代码拿到的是Promise对象而非实际数值。
正确的代码实现:
io.on('connection', (socket) => { // 将socket事件回调声明为async函数 socket.on('direction vote', async (individualVote) => { let voteCount = 1; let yesVotes = 1; // 用await直接获取countDocuments的实际结果,代码会等待Promise解析完成 const voters = await Player.countDocuments({}); console.log('voters: ' + voters); // 处理投票统计 if (individualVote === 'yes') { yesVotes++; voteCount++; console.log('yesVotes: ' + yesVotes); } // 此时voters是实际数值,可正确进行比较 if (voteCount === voters) { // 这里补充voteResult的逻辑示例 const voteResult = { yes: yesVotes, no: voteCount - yesVotes }; // 向所有客户端发送投票结果 io.emit('direction vote result', voteResult); } }); });
关键说明:
- 将事件回调改为async函数:只有在async函数内部才能使用await关键字,这样才能等待Promise完成。
- 直接await获取结果:不需要单独封装async函数,直接在回调中
await Player.countDocuments({}),这样代码会暂停在这里,直到Promise解析出实际的计票数值,再继续执行后续代码。 - 避免提前使用未解析的值:所有依赖
voters的逻辑(比如比较voteCount === voters)必须放在await语句之后,确保拿到的是实际数值而非Promise对象。
你之前的错误写法中,调用count()后直接赋值给voters,但async函数返回的是Promise对象,不是实际数值,而且后续代码没有等待这个Promise完成就执行了,所以比较逻辑永远不会成立。
内容的提问来源于stack exchange,提问作者SleepyWakes
相关产品推荐
相关产品推荐

