异步猫鼬查询问题

时间:2019-07-04 06:43:32

标签: node.js mongoose

这是我从数据库中获得的数组,我们称其为 product_list

{
        "seller": "5cee0e69f67e171ac8ef14c7",
        "products": [...]
},
{
        "seller": "5d1c36910aec8934cefdda8e",
        "products": [...]
}

我想发送相同的数组,但是将卖方字段转换为完整的卖方对象。在给定的示例中将是这些。

{
        "_id": "5cee0e69f67e171ac8ef14c7",
        "name": "Will"
},
{
        "_id": "5d1c36910aec8934cefdda8e",
        "name" : "Jess"
}

所以我想要的输出是

{
        "seller": {
             "_id": "5cee0e69f67e171ac8ef14c7",
             "name": "Will"
        },
        "products": [...]
},
{
        "seller": {
             "_id": "5d1c36910aec8934cefdda8e",
             "name": "Jess"
        },
        "products": [...]
}

我尝试了以下

product_list.forEach(element => {
     User.findById(element.seller, function(err, user){
         element.seller = user;
     };
});

我正在尝试从 product_list 对象获取所有卖方ID,将其转换为具有User.findById的完整对象,然后返回更新的product_list。但是问题是我对异步代码不太满意,由于当我用res.json(product_list)返回对象时,猫鼬调用是回调,所以猫鼬查询未完成,并且我接收了未经修改的对象。 / p>

我尝试了诺言并等待,但是我没有得到任何结果。

希望您能理解我的解释,并非常感谢您。

1 个答案:

答案 0 :(得分:0)

您可以尝试使用这种方法,将User.findById包装,然后可以使用异步/等待模式。

// Wrapper function for User.findById. We could use utils.promisify for this.
function getUserById(id) {
    return new Promise((resolve, reject) => {
        User.findById(id, (err, result) => {
            if (err) {
                reject(err);
            } else {
                resolve(result);
            }
        })
    });
}

async function getSalesDetails(productList) {

    for(let product of productList) {
        let userDetails = await getUserById(product.seller);
        product.seller = userDetails; 
    }

    return productList;
}

async function testGetSalesDetails() {
    let productList = [{
        "seller": "5cee0e69f67e171ac8ef14c7",
        "products": [1,2,3]
    },{
        "seller": "5d1c36910aec8934cefdda8e",
        "products": [4,5,6]
    }];

    let productListWithSeller = await getSalesDetails(productList);
    console.info("Product list (with seller): ", productListWithSeller);
}

testGetSalesDetails();

您还可以使用utils.promisify生成getUserById函数(非常方便!),例如:

const getUserById = util.promisify(User.findById);