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

在Mongo查询中无法调用async.auto父级回调:cb is not a function

解决async.auto中调用cb时报错'cb is not a function'的问题

问题场景

在Sails.js中结合MongoDB与async.js的async.auto方法时,创建新Mongo连接执行find查询后,尝试调用async.auto的回调函数cb传递结果,却触发cb is not a function错误。代码执行层级为:fun1(cb) -> Mongo.connect -> db.find(results) -> return cb(null, results)

用户提供的示例代码:

async.auto(
    {
        fun1: function (cb) {
               // 自定义逻辑
               return cb(null, true);
        },
        fun2: [
            'fun1',
            function (results, cb) {
                const querySearch = {
                    id,
                };

                MongoClient.connect(url, async function (err, db) {
                    if (err) {
                        console.error(err);
                        return cb(err, false);
                    }

                    await db
                        .collection(colName)
                        .find(
                            querySearch,
                            async function (err, results) {
                                if (err) {
                                    console.error(err);
                                    return cb(err, false);
                                }
                                console.log(results);
                                return cb(null, results); // 报错位置:Error: cb is not a function
                            }
                        );
                    db.close();
                });
            },
        ],
        fun3: [
            'fun2',
            function (results, cb) {
               return cb(null, true);
            },
        ],
    },
    function (err, results) {
        if(err){
            console.error(err);
            res.negotiate('Unexpected Error Occured!')
        }

        res.ok('Successfully');
    }
);

错误原因

  1. async/await与回调混用:在MongoClient.connect和find的回调中使用async关键字,会将回调包装为异步函数,破坏原有的作用域关联,导致内部无法正确引用async.auto的cb函数;同时await对带回调的find方法无效(该模式下find不返回Promise)。
  2. MongoDB find方法使用错误:带回调的find返回的是查询游标,而非直接结果集,回调的第二个参数是游标对象,不是预期的查询数据。
  3. 连接提前关闭:db.close()在find操作完成前执行,会中断数据库操作,进一步导致回调逻辑失效。

解决方案

将MongoDB操作改为Promise风格,配合async/await使用,避免回调嵌套,同时正确处理游标与连接关闭:

async.auto(
    {
        fun1: function (cb) {
            // 自定义逻辑
            return cb(null, true);
        },
        fun2: [
            'fun1',
            async function (results, cb) {
                const querySearch = { id };
                let db;
                try {
                    // 用Promise风格获取数据库连接
                    db = await MongoClient.connect(url);
                    const collection = db.collection(colName);
                    // 将find游标转换为实际结果数组
                    const queryResults = await collection.find(querySearch).toArray();
                    // 传递结果给async.auto回调
                    cb(null, queryResults);
                } catch (err) {
                    console.error(err);
                    cb(err, false);
                } finally {
                    // 确保操作完成后关闭连接,避免泄露
                    if (db) await db.close();
                }
            },
        ],
        fun3: [
            'fun2',
            function (results, cb) {
                return cb(null, true);
            },
        ],
    },
    function (err, results) {
        if (err) {
            console.error(err);
            return res.negotiate('Unexpected Error Occured!');
        }
        res.ok('Successfully');
    }
);

关键修改点

  • 将fun2的处理函数改为async函数,内部用await处理MongoDB的Promise操作,取消嵌套回调。
  • MongoClient.connect去掉回调,直接通过await获取数据库实例。
  • find方法不使用回调,通过toArray()将游标转换为结果数组,并用await等待执行完成。
  • 用try/catch/finally捕获错误,确保无论操作成功或失败都关闭数据库连接。
  • 正确引用async.auto的cb函数,传递错误或查询结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:25:55