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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 15:24:03