如何使用promise和forEach循环来循环使用mongoDB?我想填充一个数组

我试图遍历MongoDB数据库中的元素并将值保存到Array中。 但是,经过数小时的奋斗,我无法完成任务。

这是我的代码:

//shopController.js

const Product = require('../models/product');
const User = require('../models/user');


exports.getcart = (req,res,next) => {
    const productIds = [];
    const productsArr = [];
    let userData = null;

    User.findById(req.user._id)
        .then(user => {
            userData = user;
            userData.cart.items.map(prodId => {
                productIds.push(prodId.productId);
            }) 
            console.log(productIds); // [ 5dc1b6ace13a97588620d6c6,5dc1b6ace13a97588620d6c6 ]
            return productIds;
        })
        .then(prodIds => {
            prodIds.forEach(prodId => {
                Product.findById(prodId)
                    .then(product => {
                        productsArr.push(product);
                    })
                    .catch(err => console.log(err))
            })
            console.log(productsArr); // []
        })
        .catch((err) => {
            const error = new Error(err);
            error.httpStatusCode = 500;
            return next(error);
        });
}

不要介意第一个输出,它打算两次显示相同的ID。 我记录productsArr[]时的结果始终是一个空数组,除了我将console.log(productsArr); 放在里面的{strong} forEach()循环之外,这是我不想要的,因为它被记录得太多了,我无法呈现这样的EJS页面。

render函数如下所示:

res.render('shop/cart',{
                path: '/cart',docTitle: 'Cart',products: productsArr,userData: userData
            });

一旦我尝试访问forEach()循环的products 外部,我就无法将productsArr[]放入productsArr[]有一个空数组,所以我不知道该怎么做。

您有什么建议吗?

谢谢!

czh28690 回答:如何使用promise和forEach循环来循环使用mongoDB?我想填充一个数组

您需要使用Promise.prototype.all在Promises全部解析后呈现它,没有其他方法来获取填充的productsArr数组。

尝试一下:

//shopController.js

const Product = require('../models/product');
const User = require('../models/user');


exports.getCart = (req,res,next) => {
    const productIds = [];
//    const productsArr = []; not needed anymore
    let userData = null;

    User.findById(req.user._id)
        .then(user => {
            userData = user;
            userData.cart.items.map(prodId => {
                productIds.push(prodId.productId);
            })
            console.log(productIds); // [ 5dc1b6ace13a97588620d6c6,5dc1b6ace13a97588620d6c6 ]
            return productIds;
        })
        .then(prodIds => {
            Promise.all(prodIds.map(prodId =>
                Product.findById(prodId)
            ).then(productsArr => {
                res.render('shop/cart',{
                    path: '/cart',docTitle: 'Cart',products: productArr,userData: userData
                });
                console.log(productsArr); // [ ... products ... ]
            }).catch(err => {
                console.log(err);
            })
        })
        .catch((err) => {
            const error = new Error(err);
            error.httpStatusCode = 500;
            return next(error);
        });
}
,

您不是在等待产品承诺完成以显示数据。您可以使用Promise.all([])函数一次等待多个promise。

 .then(prodIds => {
        Promise.all(prodIds.map(prodId => {
                return Product.findById(prodId)
                    .then(product => {
                        productsArr.push(product);
                    })
                    .catch(err => console.log(err))
            })).then(() => {
                console.log(
        })

在这里,我们将每个产品ID映射到一个承诺(Product.findById),然后将所有产品ID传递到Promise.all()函数中,该函数需要一个数组。
然后,我们等待所有诺言得到解决,并调用then函数。 这样,您可以确保在打印数据之前完成所有承诺。

本文链接:https://www.f2er.com/3157686.html

大家都在问