如何在Realm自定义解析器find()函数返回结果中遍历处理数据
问题背景
正在为自定义解析器开发函数,目标是获取集合内全部文档,返回追加了新数据的修正负载。最初单客户处理的实现代码如下:
exports = (input) => { const clientId = input._id; const openStatusId = new BSON.ObjectId("898999"); const mongodb = context.services.get("mongodb-atlas"); const clientRecords = mongodb.db("db-name").collection("clients"); const jobRecords = mongodb.db("db-name").collection("jobs"); let client = clientRecords.findOne({"_id": clientId}); const query = { "client_id": clientId}; let jobsForClient = jobRecords.count(query) .then(items => { console.log(`Successfully found ${items} documents.`) // items.forEach(console.log) return items }) .catch(err => console.error(`Failed to find documents: ${err}`)); let openJobs = jobRecords.count({"client_id": clientId,"status": openStatusId}) .then(numOfDocs => { console.log(`Found ${numOfDocs} open jobs.`) // items.forEach(console.log) return numOfDocs }) .catch(err => console.error(`Failed to find documents: ${err}`)); return Promise.all([client, jobsForClient, openJobs]).then(values => { return {...values[0], "jobs": values[1], "openJobs": values[2]} }) };
现在需要修改为获取全部客户并遍历追加对应数据,已知将let client = clientRecords.findOne({"_id": clientId});改为let clients = clientRecords.find();可以获取全部客户文档,但不清楚后续遍历处理的逻辑。
问题更新
自行修改后的代码在Realm环境运行正常,但作为GraphQL查询执行时返回报错:"message": "pending promise returned that will never resolve/reject",修改后的代码如下:
exports = (input) => { const openStatusId = new BSON.ObjectId("999999"); const mongodb = context.services.get("mongodb-atlas"); const clientRecords = mongodb.db("db-name").collection("clients"); const jobRecords = mongodb.db("db-name").collection("jobs"); const clients = clientRecords.find(); const formatted = clients.toArray().then(cs => { return cs.map((c,i) => { const clientId = c._id; const query = { "client_id": clientId}; let jobsForClient = jobRecords.count(query) .then(items => { console.log(`Successfully found ${items} documents.`) // items.forEach(console.log) return items }) .catch(err => console.error(`Failed to find documents: ${err}`)); let openJobs = jobRecords.count({"client_id": clientId,"status": openStatusId}) .then(numOfDocs => { console.log(`Found ${numOfDocs} open jobs.`) // items.forEach(console.log) return numOfDocs }) .catch(err => console.error(`Failed to find documents: ${err}`)); return Promise.all([jobsForClient, openJobs]).then(values => { return {...c, "jobs": values[0], "openJobs": values[1]} }); }) }).catch(err => console.error(`Failed: ${err}`)); return Promise.all([clients, formatted]).then(values => { return values[1] }).catch(err => console.error(`Failed to find documents: ${err}`)); };
解决方案
报错的核心原因是没有对遍历客户生成的异步任务数组做Promise聚合,导致返回结果里包含未resolve的Promise,同时存在冗余的游标等待逻辑。修正后的完整代码如下:
exports = (input) => { const openStatusId = new BSON.ObjectId("999999"); const mongodb = context.services.get("mongodb-atlas"); const clientRecords = mongodb.db("db-name").collection("clients"); const jobRecords = mongodb.db("db-name").collection("jobs"); // 直接链式返回整个异步处理链 return clientRecords.find().toArray().then(cs => { // 对每个客户的异步处理任务做聚合,等待全部完成 return Promise.all(cs.map(c => { const clientId = c._id; const query = { "client_id": clientId }; const jobsForClient = jobRecords.count(query) .catch(err => { console.error(`获取客户任务数失败: ${err}`); return 0; // 出错时返回默认值,避免全局失败 }); const openJobs = jobRecords.count({"client_id": clientId,"status": openStatusId}) .catch(err => { console.error(`获取客户待办任务数失败: ${err}`); return 0; }); return Promise.all([jobsForClient, openJobs]).then(values => { return {...c, "jobs": values[0], "openJobs": values[1]} }); })); }).catch(err => { console.error(`处理客户数据失败: ${err}`); throw err; // 主动抛出错误,避免Promise悬而未决 }); };
核心修改点
- 去掉了无意义的游标对象等待逻辑,直接返回完整的异步处理链,保证最外层返回的Promise可以正确resolve到处理后的客户数组
- 对
map生成的每个客户的异步处理任务,用Promise.all包裹聚合,确保所有附加字段计算完成后再统一返回 - 增加了异常兜底逻辑,单个查询出错时返回默认值,避免单个客户查询失败导致整个请求崩溃
- 外层捕获异常后主动抛出,让GraphQL可以拿到明确的错误信息,不会出现悬而未决的Promise
内容的提问来源于stack exchange,提问作者poca
相关产品推荐
相关产品推荐

