Nodejs mongoose数据库怎么同步读取数据?

Nodejs mongoose数据库怎么同步读取数据?

var newOrderList = {shopPlace : String}
async.map(orderList,function(oneOrder,cb){
Shop.findOne({‘name’: oneOrder.shopName},function(err,shop){
newOrderList.shopPlace = shop.place;
cb(null,newOrderList)
})
},function(err,results){
res.render(‘userOrderRecord’,{
,‘orderList’: results
});
})

上述代码回调函数中newOrderList得到的是同一个值,但我希望Shop读取数据库的过程是同步的,newOrderList传给results四个不同的值,有什么方法?


2 回复

要解决你提到的问题,你需要确保每个异步操作都正确地完成,并且每个结果都能被独立地处理。Mongoose 提供了 Promise 和 async/await 语法来帮助你更方便地处理这些异步操作。下面是一个使用 async/await 的示例代码,它能够确保每个数据库查询都是独立进行的,并且每个查询的结果都会被正确地传递到最终的结果列表中。

示例代码

const mongoose = require('mongoose');
const async = require('async');

// 假设你已经连接到 MongoDB 并定义了 Shop 模型
// mongoose.connect('mongodb://localhost:27017/mydatabase', { useNewUrlParser: true, useUnifiedTopology: true });

const orderList = [
    { shopName: 'Shop A' },
    { shopName: 'Shop B' },
    { shopName: 'Shop C' },
    { shopName: 'Shop D' }
];

async function processOrders() {
    const results = await Promise.all(orderList.map(async (oneOrder) => {
        const shop = await Shop.findOne({ name: oneOrder.shopName }).exec();
        if (!shop) {
            throw new Error(`Shop not found for ${oneOrder.shopName}`);
        }
        return {
            ...oneOrder,
            shopPlace: shop.place
        };
    }));

    // 渲染页面
    res.render('userOrderRecord', {
        orderList: results
    });
}

processOrders().catch((err) => {
    console.error(err);
});

解释

  1. 定义订单列表:我们定义了一个包含多个订单对象的数组 orderList,每个订单对象包含一个 shopName 字段。

  2. 使用 async/await 处理异步操作:通过 Promise.allmap 方法,我们可以将每个订单对象映射为一个异步函数,该函数会查找对应的店铺信息并返回更新后的订单对象。

  3. 处理结果:一旦所有查询完成,结果会被收集到一个数组 results 中,然后传递给渲染函数。

  4. 错误处理:如果某个查询失败,可以抛出一个错误,这将在 catch 块中被捕获并处理。

这种方法确保了每个数据库查询都是独立执行的,并且结果是按顺序处理的。这样可以避免之前遇到的由于异步操作导致的结果覆盖问题。


在Node.js中使用Mongoose操作数据库时,默认情况下所有操作都是异步的。由于JavaScript的事件循环机制,异步操作不会阻塞主线程,而是通过回调函数来处理结果。然而,在你的例子中,由于异步操作的存在,newOrderList会被多次修改,导致最后的结果是一样的。

为了实现你所描述的需求——让newOrderList传给results四个不同的值,并且确保每个findOne操作都完成后再进行下一步操作,你可以使用async/await语法来简化异步操作的逻辑。这样可以让你的代码看起来更像同步代码,但实际上还是异步执行的。

下面是一个改进后的版本:

const async = require('async');
const mongoose = require('mongoose');

// 假设你已经有了一个Mongoose模型 `Shop`
const Shop = mongoose.model('Shop', new mongoose.Schema({
    name: String,
    place: String
}));

// 你的订单列表
const orderList = [
    {shopName: 'shop1'},
    {shopName: 'shop2'},
    {shopName: 'shop3'},
    {shopName: 'shop4'}
];

// 使用 async/await 来获取结果
async function getNewOrderList() {
    const results = await Promise.all(
        orderList.map(async (oneOrder) => {
            const shop = await Shop.findOne({name: oneOrder.shopName});
            return {...oneOrder, shopPlace: shop.place};
        })
    );

    // 渲染视图
    res.render('userOrderRecord', {
        'orderList': results
    });
}

getNewOrderList().catch(err => console.error(err));

在这个示例中,我们首先导入了必要的模块,然后定义了一个getNewOrderList函数,它使用Promise.all和数组的map方法来并行执行所有的查询。await关键字确保每个查询完成后才会继续执行下一个步骤,从而保证了newOrderList会包含不同的值。

这种方法避免了回调地狱(callback hell),使得代码更加清晰易读。

回到顶部