Nodejs 数据库怎么实现同步查询?

Nodejs 数据库怎么实现同步查询?

 pusher.getUsers(function(err,da){

var data=da; MongoClient.connect(“mongodb://localhost:27017/test”, function(err, db) {

for(var i=0;i<data.length;i++) { var col= db.collection(‘test’); var id=data[i].id.toString();

col.count({"FakeId":id}, function(err, count) {

      // return callback(count,)
     if(count==0)
     { console.log(count);
         pusher.getUserDetail(data[i].id,function(err,data){
             console.log(data.id);
             col.insert(data,function(err,result){
                 console.log(result);
             });



         })

     }



});

} });

遍历Data数组,并判断data里面的数据是否存在数据库中,不存在的话插入数据库。col.count异步执行,(有没有办法同步执行)在异步函数里面使用data[i].id 里面的i不是对应是不对应的怎么解决?


6 回复

要实现Node.js中的数据库同步查询,通常需要使用一些同步工具或模式来处理异步操作。然而,Node.js本身是基于事件循环的非阻塞I/O模型,因此它并不直接支持同步操作。但是,我们可以使用一些技巧来模拟同步行为,比如使用async/await语法结合Promise。

以下是一个改进后的代码示例,展示了如何使用async/await来处理异步操作,从而模拟同步查询的行为:

const MongoClient = require('mongodb').MongoClient;
const Pusher = require('./pusher'); // 假设你有一个Pusher类

async function processUsers() {
    try {
        const users = await new Promise((resolve, reject) => {
            pusher.getUsers((err, da) => {
                if (err) return reject(err);
                resolve(da);
            });
        });

        const client = await MongoClient.connect("mongodb://localhost:27017/test", { useNewUrlParser: true, useUnifiedTopology: true });
        const db = client.db();

        for (let user of users) {
            let id = user.id.toString();
            let count = await new Promise((resolve, reject) => {
                db.collection('test').countDocuments({ "FakeId": id }, (err, count) => {
                    if (err) return reject(err);
                    resolve(count);
                });
            });

            if (count === 0) {
                let userDetails = await new Promise((resolve, reject) => {
                    pusher.getUserDetail(user.id, (err, data) => {
                        if (err) return reject(err);
                        resolve(data);
                    });
                });

                await new Promise((resolve, reject) => {
                    db.collection('test').insertOne(userDetails, (err, result) => {
                        if (err) return reject(err);
                        resolve(result);
                    });
                });
            }
        }

        client.close();
    } catch (err) {
        console.error('Error:', err);
    }
}

processUsers();

解释

  1. async/await:

    • 使用async/await可以让异步代码看起来更像同步代码,从而更容易理解和维护。
  2. Promise:

    • 将回调函数包装成Promise,这样可以更容易地处理错误并保持代码结构清晰。
  3. 遍历用户数据:

    • 在遍历用户数据时,使用await来等待每个异步操作完成后再继续下一个操作。
  4. 数据库操作:

    • 使用countDocuments方法来检查记录是否存在。
    • 如果记录不存在,则从pusher获取详细信息并插入到数据库中。

通过这种方式,我们可以更好地控制异步操作的顺序,并且使代码更易于理解和维护。


你看看async库,应该对你有用

其实你可以用闭包来“留住”i的值 (function(t){“for循环里面的代码放这里”})(i)

文章第五节,场景:对数据库的连续操作 http://blog.fens.me/nodejs-async/

async确实可以符合你的需求,不过对这样操作的性能表示怀疑。mongodb没有事物机制么,redis有的。

在Node.js中,数据库查询本质上是异步的,因此不能直接实现同步查询。然而,你可以通过使用一些技术来模拟同步的行为,例如使用async/await或者通过回调的方式处理异步操作。

示例代码

下面是一个使用async/awaitPromise来模拟同步查询的例子:

const MongoClient = require('mongodb').MongoClient;
const pusher = require('./pusher'); // 假设pusher是一个已经定义好的模块

async function syncQuery() {
    try {
        const db = await new Promise((resolve, reject) => {
            MongoClient.connect("mongodb://localhost:27017/test", (err, db) => {
                if (err) reject(err);
                else resolve(db);
            });
        });

        const data = await pusher.getUsers();

        for (let item of data) {
            const id = item.id.toString();
            const count = await new Promise((resolve, reject) => {
                db.collection('test').countDocuments({ "FakeId": id }, (err, count) => {
                    if (err) reject(err);
                    else resolve(count);
                });
            });

            if (count === 0) {
                const userDetail = await new Promise((resolve, reject) => {
                    pusher.getUserDetail(item.id, (err, data) => {
                        if (err) reject(err);
                        else resolve(data);
                    });
                });

                await new Promise((resolve, reject) => {
                    db.collection('test').insertOne(userDetail, (err, result) => {
                        if (err) reject(err);
                        else resolve(result);
                    });
                });
            }
        }

        db.close();
    } catch (error) {
        console.error(error);
    }
}

syncQuery();

解释

  • async/await: 使用async/await语法可以让异步代码看起来更像同步代码,使得逻辑更加清晰。
  • Promise: Promise用于将回调函数包装成返回值的形式,从而可以方便地使用await关键字。
  • 循环处理: 在循环中使用await等待每个异步操作完成后再进行下一个操作。

这种方法避免了回调地狱,并且保持了代码的可读性和可维护性。

回到顶部