异步操作及collection.each遍历完成后如何返回结果?
异步场景下完成操作后如何返回结果?
异步操作的核心问题是代码不会按顺序同步执行,直接return肯定拿不到预期结果,常用的解决方式有这三种:
回调函数:这是最传统的处理方式,把异步完成后要执行的逻辑写成回调函数,传给异步操作。比如:
function asyncOperation(callback) { setTimeout(() => { callback(null, "异步操作完成的结果"); }, 1000); } // 调用时传入回调 asyncOperation((err, result) => { if (err) { console.error(err); return; } console.log(result); // 这里拿到异步结果 });Promise对象:把异步操作包装成Promise实例,成功时用
resolve()传递结果,失败时用reject()传递错误,后续通过.then()和.catch()处理:function asyncOperation() { return new Promise((resolve, reject) => { setTimeout(() => { resolve("异步操作完成的结果"); // 如果出错就调用 reject(new Error("出错了")); }, 1000); }); } // 调用方式 asyncOperation() .then(result => console.log(result)) .catch(err => console.error(err));async/await语法糖:这是Promise的语法糖,让异步代码看起来像同步代码一样直观。用
async标记包含异步操作的函数,用await等待Promise完成:async function getResult() { try { const result = await asyncOperation(); console.log(result); // 直接拿到结果 } catch (err) { console.error(err); } } getResult();
当collection.each遍历完成后如何返回结果?
你原来的代码拿不到结果,核心原因是**each是异步遍历**,你的函数在遍历还没完成时就已经执行了return result,这时候result还是空数组。给你两种解决思路:
方法1:用Promise包装each遍历
把整个遍历过程包裹在Promise里,当each的回调接收到collection为null时(说明遍历结束),再通过resolve返回结果:
async function getCollectionNames(arg) { const result = []; const db = MongoInternals.defaultRemoteCollectionDriver().mongo.db; const collections = db.listCollections(); return new Promise((resolve, reject) => { collections.each((err, collection) => { // 先处理错误 if (err) { reject(err); return; } // 如果collection存在,就添加到结果数组 if (collection) { result.push(collection.name); } else { // collection为null时,说明遍历完成了,返回结果 resolve(result); } }); }); } // 调用时需要用await或者.then() // 比如: // getCollectionNames().then(names => console.log(names)).catch(err => console.error(err));
方法2:用toArray()更简洁处理
其实MongoDB的Cursor(listCollections()返回的就是Cursor)自带toArray()方法,它会异步把所有文档转成数组,用起来比each方便太多:
async function getCollectionNames(arg) { const db = MongoInternals.defaultRemoteCollectionDriver().mongo.db; // 用await等待toArray()完成,直接拿到所有collection的数组 const collections = await db.listCollections().toArray(); // 提取name字段返回 return collections.map(collection => collection.name); } // 调用示例: // const names = await getCollectionNames(); // console.log(names);
这个方法不仅代码更简洁,还避免了手动遍历的繁琐,推荐使用这种方式~
内容的提问来源于stack exchange,提问作者Mag Ron
相关产品推荐
相关产品推荐

