在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'); } );
错误原因
- async/await与回调混用:在
MongoClient.connect和find的回调中使用async关键字,会将回调包装为异步函数,破坏原有的作用域关联,导致内部无法正确引用async.auto的cb函数;同时await对带回调的find方法无效(该模式下find不返回Promise)。 - MongoDB
find方法使用错误:带回调的find返回的是查询游标,而非直接结果集,回调的第二个参数是游标对象,不是预期的查询数据。 - 连接提前关闭:
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
相关产品推荐
相关产品推荐

