You need to enable JavaScript to run this app. NodeJS+Express环境下Await关键字未等待Promise执行完成问题
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS+Express环境下Await关键字未等待Promise执行完成问题

问题根因

你遇到的报错本质是异步逻辑没有正确等待,3个核心错误点:

  • resize函数内部的异步自执行函数没有被外部感知,调用resize()会直接返回,不会等待图片调整尺寸完成
  • preprocess使用回调式API,没有封装为Promise,调用后直接返回undefined,不会等待图片读取、张量构造完成
  • 路由处理函数是同步函数,内部没有用await等待异步操作执行,直接走到了predict步骤

修改方案

1. 改造resize函数为异步函数

直接去掉内部的异步自执行包裹,改为返回Promise的async函数:

async function resize(imagePath) {
  const options = {
    images: [imagePath],
    width: 224,
    height: 224,
    quality: 90
  };
  await resizeOptimizeImages(options);
  console.log("resized");
}

2. 改造preprocess函数为Promise版本

把回调式的get-image-data调用封装为Promise,异步结果通过resolve返回:

function preprocess(imagePath) {
  return new Promise((resolve, reject) => {
    image(imagePath, (err, imageData) => {
      if (err) return reject(err);
      const numChannels = 3;
      const numPixels = imageData.width * imageData.height;
      const values = new Int32Array(numPixels * numChannels);
      const pixels = imageData.data;
      for (let i = 0; i < numPixels; i++) {
        for (let channel = 0; channel < numChannels; ++channel) {
          values[i * numChannels + channel] = pixels[i * 4 + channel];
        }
      }
      const outShape = [imageData.height, imageData.width, numChannels];
      const input = tf.tensor3d(values, outShape, 'float32');
      resolve(input);
    });
  });
}

3. 修改路由处理函数为async函数

按顺序等待异步操作完成后再执行预测,补充异常捕获和模型加载判断:

app.post('/classify', upload.single('file'), async (req, res) => {
  // 避免模型未加载完成就处理请求
  if (!model) {
    return res.status(503).json({ error: '模型加载中,请稍后重试' });
  }
  try {
    // 取当前上传文件的本地路径,不要用全局变量避免并发请求污染
    const imagePath = req.file.path;
    // 等待尺寸调整完成
    await resize(imagePath);
    // 等待预处理完成获取输入张量
    const input = await preprocess(imagePath);
    // 执行预测
    const prediction = model.predict(input);
    // 返回预测结果,这里可以根据你的模型输出调整格式
    res.json({
      result: prediction.arraySync()
    });
    // 清理张量避免显存泄漏
    input.dispose();
    prediction.dispose();
  } catch (err) {
    console.error('请求处理失败:', err);
    res.status(500).json({ error: '图像处理失败' });
  }
});

额外注意

你原来的全局imagePath变量必须删掉,多个用户同时上传时会互相覆盖导致逻辑错误,所有参数都从当前请求的req.file中获取即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 03:06:06