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

如何让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);
        }
    }); 
});

关键说明:

  1. 将事件回调改为async函数:只有在async函数内部才能使用await关键字,这样才能等待Promise完成。
  2. 直接await获取结果:不需要单独封装async函数,直接在回调中await Player.countDocuments({}),这样代码会暂停在这里,直到Promise解析出实际的计票数值,再继续执行后续代码。
  3. 避免提前使用未解析的值:所有依赖voters的逻辑(比如比较voteCount === voters)必须放在await语句之后,确保拿到的是实际数值而非Promise对象。

你之前的错误写法中,调用count()后直接赋值给voters,但async函数返回的是Promise对象,不是实际数值,而且后续代码没有等待这个Promise完成就执行了,所以比较逻辑永远不会成立。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 04:06:36