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

JavaScript中结合async/await与Promise,优化循环调用resolveName的代码

问题修复指南:让resolveName在循环中正常执行

我帮你梳理下代码里的几个关键问题,然后一步步修复,确保resolveName能在循环中正确返回解析后的公司名称:

1. 先解决resolveName的核心问题

当前你的resolveName函数有两个致命问题:

  • 没有返回数据库查询的Promise,导致await resolveName()根本拿不到结果
  • 函数里直接使用res对象报错(这个函数没接收req/res参数),错误处理应该交给上层的接口函数

修正后的resolveName改成async函数,直接返回Promise结果:

async function resolveName(c_id) {
  try {
    // 用await替代.then,代码更清晰
    const company = await localDB.find({
      selector: { type: 'company', _id: c_id },
      fields: ['companyName'],
    });
    // 存在数据就返回名称,否则返回null
    return company.docs.length >= 1 ? company.docs[0].companyName : null;
  } catch (err) {
    console.log('解析公司名称出错:', err);
    // 把错误抛给上层处理,不要在这个函数里操作res
    throw err;
  }
}

2. 修复循环变量的全局污染问题

你的for循环里的i和j没加let/const声明,会变成全局变量,导致循环逻辑混乱,必须加上声明。

3. 重构getAllItems函数,统一用async/await

原来的函数混合了.then()和async/await,代码可读性差,我们统一用async/await,同时处理所有错误:

基础修复版(串行请求)

const getAllItems = async function(req, res) {
  try {
    // 先获取所有item数据
    const result = await localDB.find({
      selector: { type: 'item' },
      fields: ['_id', 'itemNumber', 'itemName', 'compatablities', 'companyID'],
      sort: ['_id']
    });

    if (!result) {
      return res.status(200).json({ refinedResult: [] });
    }

    const refinedResult = [];
    // 用let声明循环变量i
    for (let i = 0; i < result.docs.length; i++) {
      const doc = result.docs[i];
      // 解析当前item的公司名称
      const companyName = await resolveName(doc.companyID);
      const parentItem = {
        itemName: doc.itemName,
        itemNumber: doc.itemNumber,
        companyID: doc.companyID,
        parentItemNo: "Parent",
        companyName // 把解析后的名称加进去
      };
      refinedResult.push(parentItem);

      // 处理兼容性项,先判断compatablities是否存在,避免报错
      const compatList = doc.compatablities || [];
      // 用let声明j
      for (let j = 0; j < compatList.length; j++) {
        const compat = compatList[j];
        // 解析兼容性项的公司名称
        const compatCompanyName = await resolveName(compat.companyID);
        const compatItem = {
          itemName: doc.itemName,
          itemNumber: compat.itemNumber,
          companyID: compat.companyID,
          parentItemNo: doc.itemNumber,
          companyName: compatCompanyName
        };
        refinedResult.push(compatItem);
      }
    }

    return res.status(200).json({ refinedResult });
  } catch (err) {
    console.log('获取物品列表出错:', err);
    return res.status(500).json({ error: err.message });
  }
};

性能优化版(并行请求)

上面的代码是串行调用resolveName,如果数据量大,接口会很慢。我们可以先收集所有需要解析的公司ID,一次性并行查询,大幅提升速度:

const getAllItems = async function(req, res) {
  try {
    const result = await localDB.find({
      selector: { type: 'item' },
      fields: ['_id', 'itemNumber', 'itemName', 'compatablities', 'companyID'],
      sort: ['_id']
    });

    if (!result) {
      return res.status(200).json({ refinedResult: [] });
    }

    // 收集所有需要解析的公司ID,用Set去重
    const allCompanyIds = new Set();
    result.docs.forEach(doc => {
      allCompanyIds.add(doc.companyID);
      (doc.compatablities || []).forEach(compat => {
        allCompanyIds.add(compat.companyID);
      });
    });

    // 并行查询所有公司名称,构建ID到名称的映射表
    const companyNameMap = {};
    await Promise.all(Array.from(allCompanyIds).map(async (id) => {
      const name = await resolveName(id);
      companyNameMap[id] = name;
    }));

    const refinedResult = [];
    for (let i = 0; i < result.docs.length; i++) {
      const doc = result.docs[i];
      const parentItem = {
        itemName: doc.itemName,
        itemNumber: doc.itemNumber,
        companyID: doc.companyID,
        parentItemNo: "Parent",
        companyName: companyNameMap[doc.companyID]
      };
      refinedResult.push(parentItem);

      const compatList = doc.compatablities || [];
      for (let j = 0; j < compatList.length; j++) {
        const compat = compatList[j];
        const compatItem = {
          itemName: doc.itemName,
          itemNumber: compat.itemNumber,
          companyID: compat.companyID,
          parentItemNo: doc.itemNumber,
          companyName: companyNameMap[compat.companyID]
        };
        refinedResult.push(compatItem);
      }
    }

    return res.status(200).json({ refinedResult });
  } catch (err) {
    console.log('获取物品列表出错:', err);
    return res.status(500).json({ error: err.message });
  }
};

这样修改后,你的代码就能正常工作,而且性能也更好啦。


内容的提问来源于stack exchange,提问作者Mike T

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 16:58:12