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

使用await Promise.all()后无法访问已解析Promise的属性怎么办?

问题描述

我有一个图片数组,想要一次性上传至MongoDB:

images = [{ 
    id: 123,
    alt: "my image",
    buffer: <Buffer>,
    mimetype: "image/jpeg"
}]

我知道应该使用Promise.all()来实现,但对Promise不太熟悉,写出了以下代码(其中Image是我的Mongoose Schema):

const uploaded_images = images.map(img => {
    return {
        id: img.id,
        promise: Image.create({
            image: { data: img.buffer, contentType: img.mimetype },
            alt: img.alt,
        })
    };
});

await Promise.all(uploaded_images.map(img => img.promise));

但尝试访问新上传图片的_id属性时,结果是undefined:

uploaded_images.forEach(img => {
    console.log(img.promise);        // 输出 Promise { { image: { data: new Binary(...), contentType: 'image/jpeg' }, alt: 'my image', _id: new ObjectId(...) } }
    console.log(img.promise._id);    // 输出 Undefined
})

我该如何访问_id属性?

经过进一步测试:在await Promise.all()语句前打印数组,得到 [{ id: '013150333796129177', promise: Promise { <pending> } }];在该语句后打印数组,得到[{ id: '013150333796129177', promise: Promise { [Object] } }]。这是否意味着Promise已解析?为何无法访问对象?

解决方案

问题根源

你看到的Promise { [Object] }只是Promise对象的状态展示,即使Promise已经resolve,你也不能直接通过promise._id访问结果——因为img.promise本身还是Promise实例,不是resolve后的文档对象。

正确实现方式

你需要收集Promise.all()返回的已解析结果,而不是去原数组里的Promise实例上找数据。修改代码如下:

// 先把每个图片对应的创建Promise和原id关联起来
const imagePromises = images.map(img => ({
  originalId: img.id,
  createPromise: Image.create({
    image: { data: img.buffer, contentType: img.mimetype },
    alt: img.alt
  })
}));

// 等待所有Promise完成,拿到解析后的文档数组
const uploadedDocs = await Promise.all(imagePromises.map(item => item.createPromise));

// 把原id和新的文档(包含_id)对应起来
const resultMap = uploadedDocs.map((doc, index) => ({
  originalId: imagePromises[index].originalId,
  uploadedDoc: doc,
  _id: doc._id // 直接获取_id
}));

// 现在可以正常访问_id了
resultMap.forEach(item => {
  console.log(item.originalId, item._id);
});

简化版实现

如果不需要保留原id和新文档的关联,直接用更简洁的写法:

const uploadedDocs = await Promise.all(images.map(img => 
  Image.create({
    image: { data: img.buffer, contentType: img.mimetype },
    alt: img.alt
  })
));

// 直接遍历结果数组获取_id
uploadedDocs.forEach(doc => {
  console.log(doc._id);
});

补充说明

  • Promise.all()会返回一个数组,数组里的元素是对应位置Promise resolve后的结果,顺序和传入的Promise数组完全一致。
  • 即使Promise已经处于resolved状态,你也必须通过await或者.then()来获取它的结果,不能直接从Promise实例上读取属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:25:50