Node.js中遍历content数组匹配asin对应product数据并存入数据库问题
问题原因
你的代码核心问题是Array.map配合异步函数的使用逻辑错误:async函数执行后返回的是Promise对象,你没有等待所有异步数据库查询操作执行完成,就直接使用原始的content数组创建BlogPost存入数据库,此时product字段还未完成赋值,自然无法得到预期结果。
修复后代码
exports.createBlogPost = async (req, res) => { try { const content = req.body.content // 用Promise.all等待所有异步查询执行完成,得到更新后的content数组 const updatedContent = await Promise.all( content.map(async (element) => { const product = await Product.findOne({ asin: element.asin }) return { ...element, product: product } }) ) console.log(updatedContent) const post = new BlogPost({ postTitle: req.body.postTitle, postQuery: req.body.postQuery, content: updatedContent, mainImage: req.file }) console.log("Saved: " + post) await post.save() if(post) { return res.status(200).json({ success: true, message: 'Saved blog post successfully', post: post }) } } catch(err) { console.log(err) // 补充错误响应,避免请求挂起 return res.status(500).json({ success: false, message: '保存博客文章失败' }) } }
可选性能优化
如果content数组长度较大,逐次调用findOne会产生多次数据库请求,性能较低,可改成批量查询减少数据库交互次数:
exports.createBlogPost = async (req, res) => { try { const content = req.body.content // 提取所有asin列表 const asinList = content.map(item => item.asin) // 一次查询所有匹配的product const productList = await Product.find({ asin: { $in: asinList } }) // 构造asin到product的映射表,方便快速匹配 const productMap = new Map(productList.map(product => [product.asin, product])) // 遍历组装新的content数组 const updatedContent = content.map(element => ({ ...element, product: productMap.get(element.asin) })) const post = new BlogPost({ postTitle: req.body.postTitle, postQuery: req.body.postQuery, content: updatedContent, mainImage: req.file }) await post.save() return res.status(200).json({ success: true, message: 'Saved blog post successfully', post: post }) } catch(err) { console.log(err) return res.status(500).json({ success: false, message: '保存博客文章失败' }) } }
内容的提问来源于stack exchange,提问作者Philippe
相关产品推荐
相关产品推荐

