无法使用 await Promise.all() 访问已解析 promise 的属性

Cant access property of resolved promise using await Promise.all()

提问人:Oscar R 提问时间:2/13/2023 最后编辑:PhilOscar R 更新时间:2/13/2023 访问量:64

问:

我有一个图像数组,我想一次上传到MongoDB:

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

我知道你应该为此使用,但我对承诺一无所知,只能将以下内容串在一起,其中是我的 Mongoose Schema:Promise.all()Image

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));

但是,当我现在尝试访问新上传图像的属性时,我得到_idundefined

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

如何进入酒店?_id

经过更多测试:在我控制台记录数组时,在行之前,我得到 .然后,当我控制台记录它时,在那一行之后,我得到.这是否意味着它已经解决了?为什么我无法访问对象?await Promise.all() [{ id: '013150333796129177', promise: Promise { <pending> } }][{ id: '013150333796129177', promise: Promise { [Object] } }]

node.js 猫鼬 承诺

评论

0赞 Phil 2/13/2023
如果不使用它来创建实体,该属性有什么用?id
0赞 Oscar R 2/13/2023
@Phil 这是因为这些是产品的图像,我将在此代码之后创建这些图像。我需要将新创建的图像添加为该产品架构中的外键,并且需要旧的 id 属性才能将正确的图像映射到正确的产品属性
0赞 Phil 2/13/2023
是财产还是?bufferBuffer
0赞 Oscar R 2/13/2023
@Phil它是小写的缓冲区

答:

1赞 Phil 2/13/2023 #1

等待所有属性解析不会将它们从 promise 更改为 data; 将永远是一个承诺。.promise.promise

我想你想要更多这样的东西......

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

uploaded_images.forEach((img) => {
  console.log(img.id); // original id
  console.log(img.image._id); // Image entity id
});

回调中使用的异步函数将返回一个承诺,该承诺在完成时解析。一旦它们全部解决,使用这一系列承诺将完成。map()Image.create()Promise.all()


以上内容仍然单独插入文档。如果要批量插入,则需要将数组传递给 Image.insertMany()

const imageDocs = await Image.insertMany(
  images.map(({ alt, buffer, mimetype }) => ({
    alt,
    image: { data: buffer, contentType: mimeType },
  })),
  {
    ordered: true,
  }
);

const uploaded_images = imageDocs.map((image, i) => ({
  id: images[i].id,
  image,
}));

请注意,将创建的文档与原始数组中的属性相结合现在有点麻烦。id

评论

0赞 Oscar R 2/13/2023
这是否一次将每个图像上传到数据库?如果这是唯一的方法,这是可以接受的,但我希望不要向我的数据库提出太多请求