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

Async函数未执行后续代码求助:Mongoose连接状态检测异常

MongoDB连接异步等待问题修复

问题场景

我想构建一个async函数,确保后续步骤必须等待该函数执行完成后再启动。编写了连接MongoDB服务器及检测连接状态的模块,两个函数单独运行正常,但调用时await checkState()之后的console.log("Do this next")从未执行,怀疑是resolve的使用有问题。

原数据库配置模块代码

const mongoose = require('mongoose');
const mongoServer = `mongodb://127.0.0.1/my_database`;
const consoleColor = { green: '\x1b[42m%s\x1b[0m', yellow: '\x1b[43m%s\x1b[0m', red: '\x1b[41m%s\x1b[0m' }

exports.connectMongoose = () => {
    mongoose.connect(mongoServer, { useNewUrlParser: true });
}

exports.checkState = () => {
    const mongooseState = mongoose.STATES[mongoose.connection.readyState];
    return new Promise((resolve) => {
        if (mongooseState === 'connected') {
            console.log(consoleColor.green, `Mongoose is ${mongooseState}.`);
            resolve();
        } else if (mongooseState === 'connecting') {
            console.log(`Mongoose is ${mongooseState}.`);
            setTimeout(() => {
                this.checkState();
            }, 1000);
        } else {
            console.log(consoleColor.red, `Mongoose is ${mongooseState}.`);
        }
    });
} 

调用代码

const dbconfig = require('./dbconfig')

dbconfig.connectMongoose()

const testAwait = async () => {
    await dbconfig.checkState();
    console.log("Do this next");
}
testAwait()

问题分析

  • checkState的Promise永远无法resolve(当状态为connecting时):当连接处于connecting状态时,通过setTimeout递归调用this.checkState(),但这里的this指向setTimeout的回调上下文,并非模块导出对象,递归调用的是不存在的方法;就算调用正确,递归产生的新Promise和外层返回的Promise没有关联,外层Promise永远不会被resolve,导致await一直挂起。
  • connectMongoose未利用mongoose.connect的原生Promise:mongoose.connect本身返回Promise,无需手动轮询状态,直接利用原生Promise更可靠。

修复方案

方案一:修复原有checkState函数

修改checkState,确保递归时关联外层Promise,同时处理连接失败的reject场景:

const mongoose = require('mongoose');
const mongoServer = `mongodb://127.0.0.1/my_database`;
const consoleColor = { green: '\x1b[42m%s\x1b[0m', yellow: '\x1b[43m%s\x1b[0m', red: '\x1b[41m%s\x1b[0m' }

exports.connectMongoose = () => {
    mongoose.connect(mongoServer, { useNewUrlParser: true });
}

exports.checkState = () => {
    return new Promise((resolve, reject) => {
        const check = () => {
            const mongooseState = mongoose.STATES[mongoose.connection.readyState];
            if (mongooseState === 'connected') {
                console.log(consoleColor.green, `Mongoose is ${mongooseState}.`);
                resolve();
            } else if (mongooseState === 'connecting') {
                console.log(`Mongoose is ${mongooseState}.`);
                setTimeout(check, 1000);
            } else {
                const errMsg = `Mongoose is ${mongooseState}.`;
                console.log(consoleColor.red, errMsg);
                reject(new Error(errMsg));
            }
        };
        check();
    });
} 

方案二:直接利用mongoose.connect的原生Promise(更简洁可靠)

无需手动轮询状态,直接使用mongoose.connect返回的Promise处理连接逻辑:

const mongoose = require('mongoose');
const mongoServer = `mongodb://127.0.0.1/my_database`;
const consoleColor = { green: '\x1b[42m%s\x1b[0m', yellow: '\x1b[43m%s\x1b[0m', red: '\x1b[41m%s\x1b[0m' }

// 让connectMongoose返回Promise
exports.connectMongoose = () => {
    return mongoose.connect(mongoServer, { useNewUrlParser: true })
        .then(() => {
            console.log(consoleColor.green, `Mongoose is connected.`);
        })
        .catch(err => {
            console.log(consoleColor.red, `Mongoose connection failed: ${err.message}`);
            throw err;
        });
}

对应的调用代码修改为:

const dbconfig = require('./dbconfig')

const testAwait = async () => {
    // 直接await连接Promise,连接成功后执行后续代码
    await dbconfig.connectMongoose();
    console.log("Do this next");
}
// 捕获连接失败的错误
testAwait().catch(err => console.error(err));

说明

方案二更推荐,它利用mongoose原生异步处理机制,避免手动轮询可能带来的错误,代码简洁且可靠性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 10:35:26