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

Promise新手求助:如何正确编写根据Item ID查询关联ItemType的代码

关于Promise实现物品类型查找的问题

我是Promise新手,写代码时遇到困惑,需要实现以下功能:

  • 获取Promise返回的物品类型列表
  • 遍历所有物品类型,通过Promise检查是否存在指定ID的物品
  • 存在则返回该类型,不存在则不处理

当前实现代码

public getItemTypeFromItemId(itemId: string): Promise<ItemTypeName[]> {
  console.log("Searching for ID " + itemId + " in all item types");
  return this.getItemTypes().then(itemtypes => {
    console.log("Found " + itemtypes.length + " item types.")
    let itemtypenames: ItemTypeName[] = [];
    const calls = itemtypes.map(itemtype => {
      console.log("Looking in " + itemtype.name);
      return this.getItemById(itemtype.name, itemId).then(value => {
        if (value !== undefined) {
          console.log("FOUND " + itemId + " within " + itemtype.name);
          itemtypenames.push(itemtype.name as ItemTypeName);
        }
      });
    });
    return Promise.all(calls).then(() => itemtypenames);
  });
}

自动测试用例

const PART_ID = "2A1499A5563349DAA1597EFB375FA8F2";
const CAD_ID = "24FCC02F8BD048C5881E1C63DAFC88BB";

describe('"getItemTypeFromItemId": get ItemType from item ID', async function () {
  it('Finds the good item type when the ID is present', async function () {
    await itemTypeService.getItemTypeFromItemId(PART_ID).then(itemtypenames => expect(itemtypenames[0]).to.equal("Part"));
    await itemTypeService.getItemTypeFromItemId(CAD_ID).then(itemtypenames => expect(itemtypenames[0]).to.equal("CAD"));
  });

  it('Returns `undefined` if no item with this ID exists', async function () {
    await itemTypeService.getItemTypeFromItemId("").then(itemtypenames => expect(itemtypenames.length).to.equal(0));
  });
});

优化后的实现方案

你的代码逻辑是正确的,但可以通过避免外部变量、利用Promise返回值让代码更简洁易读,同时符合Promise最佳实践。

方案1:基于then链式调用的优化

public getItemTypeFromItemId(itemId: string): Promise<ItemTypeName[]> {
  console.log(`Searching for ID ${itemId} in all item types`);
  return this.getItemTypes().then(itemtypes => {
    console.log(`Found ${itemtypes.length} item types.`);
    // 每个Promise调用返回找到的类型名或undefined
    const checks = itemtypes.map(itemtype => {
      console.log(`Looking in ${itemtype.name}`);
      return this.getItemById(itemtype.name, itemId).then(value => {
        if (value !== undefined) {
          console.log(`FOUND ${itemId} within ${itemtype.name}`);
          return itemtype.name as ItemTypeName;
        }
        // 没找到则返回undefined
        return undefined;
      });
    });
    // 等待所有检查完成后,过滤掉undefined的项
    return Promise.all(checks).then(results => results.filter(Boolean) as ItemTypeName[]);
  });
}

方案2:使用async/await更直观(推荐新手使用)

async/await语法可以让异步代码看起来像同步代码,更易理解:

public async getItemTypeFromItemId(itemId: string): Promise<ItemTypeName[]> {
  console.log(`Searching for ID ${itemId} in all item types`);
  const itemtypes = await this.getItemTypes();
  console.log(`Found ${itemtypes.length} item types.`);
  
  const results: ItemTypeName[] = [];
  // 遍历每个类型,逐个检查
  for (const itemtype of itemtypes) {
    console.log(`Looking in ${itemtype.name}`);
    const item = await this.getItemById(itemtype.name, itemId);
    if (item !== undefined) {
      console.log(`FOUND ${itemId} within ${itemtype.name}`);
      results.push(itemtype.name as ItemTypeName);
    }
  }
  
  return results;
}

如果需要保持原代码的并行检查性能,async/await版本也可以这样写:

public async getItemTypeFromItemId(itemId: string): Promise<ItemTypeName[]> {
  console.log(`Searching for ID ${itemId} in all item types`);
  const itemtypes = await this.getItemTypes();
  console.log(`Found ${itemtypes.length} item types.`);
  
  const checks = itemtypes.map(async itemtype => {
    console.log(`Looking in ${itemtype.name}`);
    const item = await this.getItemById(itemtype.name, itemId);
    return item ? (itemtype.name as ItemTypeName) : undefined;
  });
  
  const results = await Promise.all(checks);
  return results.filter(Boolean) as ItemTypeName[];
}

优化说明

  • 去掉了外部数组itemtypenames的副作用,直接通过Promise返回值传递结果
  • 使用filter(Boolean)快速过滤掉undefined的项,代码更简洁
  • async/await版本逻辑更线性,适合新手理解和调试
  • 两种优化方案都能通过你的测试用例

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 15:42:46