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

修复executeNextBatch()未始终返回Promise的Node.js异步问题

问题解决:Promise调用时出现undefined错误

问题场景

实现了一个物品列表遍历函数:若数据库存在物品对应图片则直接赋值,不存在则调用OpenAI生成图片并保存至数据库。图片生成与保存功能正常,但调用函数时触发TypeError: Cannot read properties of undefined (reading 'then')错误,错误指向executeNextBatch().then(...)代码行。已知混用then与await语法,核心问题是executeNextBatch()并非始终返回Promise,需在保留批量请求限制的前提下修复。

错误原因

executeNextBatch()函数在index >= batches.length(所有批次执行完成)时,未返回任何值(默认返回undefined),而undefined不存在.then()方法,导致调用时报错。

修复方案

修改executeNextBatch(),当所有批次执行完成后返回一个已resolved的Promise:

function executeNextBatch() {
  if (index < batches.length) {
    return executeBatch(batches[index++])
      .then(() => new Promise(resolve => setTimeout(resolve, 60000 / MAX_REQUESTS_PER_MINUTE)))
      .then(executeNextBatch);
  }
  // 新增:所有批次完成后返回resolved的Promise
  return Promise.resolve();
}

额外优化点

1. generateImageByNameAndSave函数错误处理优化

  • 混用await与.catch()会导致错误被吞掉,建议统一用try/catch处理:
    // 替换原await + .catch写法
    let newImage;
    try {
      newImage = await openai.images.generate({
        prompt: imageName,
        response_format: 'b64_json',
        n: 1,
        size: "256x256",
      },{
        validateStatus: function (status) {
          return status < 500;
        }
      });
    } catch(e) {
      console.log('imageName ' + JSON.stringify(imageName));
      console.log('e ' + JSON.stringify(e));
      if (e.data.error.message.includes('safety system')) {
        throw new Error('图片生成被安全系统拦截');
      }
      console.error(e);
      throw e;
    }
    
  • image.save(image)参数冗余,save()方法无需传入自身,直接await image.save()即可
  • 重复赋值image.merchantId,删除重复代码行

2. findImagesForObjectsOrGenerate函数可读性优化

改为async函数,用await替代then()让代码更直观:

async function findImagesForObjectsOrGenerate(listOfObjects, images, isCategory, merchantId) {
  const MAX_REQUESTS_PER_MINUTE = 1;
  const requestsPerBatch = Math.min(MAX_REQUESTS_PER_MINUTE, listOfObjects.length);

  let promises = [];
  if (listOfObjects.length > 0) {
    listOfObjects.forEach((object) => {
      const matchedImage = images.find(image => object.id === image.cloverDataId);
      if (matchedImage) {
        object.imageData = matchedImage.imageData;
      } else {
        promises.push(() => imageService.generateImageByNameAndSave(object.name, isCategory, object.id, merchantId));
      }
    });
  }

  function executeBatch(batch) {
    return Promise.all(batch.map(fn => fn()));
  }

  const batches = [];
  while (promises.length > 0) {
    batches.push(promises.splice(0, requestsPerBatch));
  }

  let index = 0;
  async function executeNextBatch() {
    if (index < batches.length) {
      await executeBatch(batches[index++]);
      await new Promise(resolve => setTimeout(resolve, 60000 / MAX_REQUESTS_PER_MINUTE));
      await executeNextBatch();
    }
  }

  await executeNextBatch();
  return listOfObjects;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:38:20