请问一个关于Nodejs回调的例子

请问一个关于Nodejs回调的例子

请问一个好像应该要嵌套的回调怎么用。。。 我定义的User

function User(user) {
this.name = user.name;
this.password = user.password;
this.type = user.type;
this.parentname = user.parentname ;

};

type是P的表示父节点,C是子节点 现在写一个子节点(C)的查询 参数:子节点的名字,父节点的名字 如果父节点不存在,直接返回错误,如果父节点存在再查子节点 现在的情况是如果父节点存在查子节点的时候,好像没有返回到最外层。。。 我也不知道我说清楚没有。。。

   User.getCC = function get(childname,parentname, callback) {
mongodb.open(function(err, db) {
	if (err) {
		return callback(err);
	}
	//获取users集合
	db.collection('users', function(err, collection) {
		if (err) {
			mongodb.close();
			return callback(err);
		}
	//查找name属性为parentname类型为P的文档
	collection.findOne({name: parentname,type : 'P'}, function(err, doc) {
		mongodb.close();
		if (!doc) {
			mongodb.close();
			err="父节点不存在";
			callback(err, null);
		}
		console.log(doc);
		
		collection.findOne({name: childname,type : 'C'}, function(err, doc) {
		
			mongodb.close();
			if (doc) {
			//封装文档为User对象
				console.log(doc);
				var user = new User(doc);
				mongodb.close();
				callback(err, user);
			} else {
				mongodb.close();
				callback(err, null);
			}
		});
	});
	
	
	
});

});

};

请大家指点一下。。。


4 回复

当然可以。根据你的描述,你希望实现一个功能,即通过给定的子节点名称和父节点名称来查询数据库,并且只有当父节点存在时才去查询子节点。你提到的代码中有一些重复调用了 mongodb.close(),这可能会导致一些问题。我们可以通过简化代码结构来解决这些问题。

以下是一个改进后的示例代码:

const User = require('./models/User'); // 假设你的User类在这个路径下

User.getCC = function(childname, parentname, callback) {
    mongodb.open((err, db) => {
        if (err) {
            return callback(err);
        }

        const collection = db.collection('users');

        // 查找父节点
        collection.findOne({ name: parentname, type: 'P' }, (err, parentDoc) => {
            if (err) {
                db.close();
                return callback(err);
            }

            if (!parentDoc) {
                db.close();
                return callback("父节点不存在", null);
            }

            // 查找子节点
            collection.findOne({ name: childname, type: 'C' }, (err, childDoc) => {
                db.close();

                if (err) {
                    return callback(err);
                }

                if (childDoc) {
                    var user = new User(childDoc);
                    return callback(null, user);
                } else {
                    return callback(null, null);
                }
            });
        });
    });
};

解释:

  1. 打开数据库连接:使用 mongodb.open 打开数据库连接。
  2. 查询父节点:使用 collection.findOne 查询 typeP 的父节点。
  3. 处理父节点查询结果
    • 如果查询出错或父节点不存在,则关闭数据库连接并返回错误信息。
    • 如果父节点存在,则继续查询子节点。
  4. 查询子节点:使用 collection.findOne 查询 typeC 的子节点。
  5. 处理子节点查询结果
    • 如果查询出错,则返回错误信息。
    • 如果子节点存在,则创建 User 对象并返回。
    • 如果子节点不存在,则返回 null

这样可以避免多次调用 mongodb.close(),确保每个查询的结果都能正确处理。希望这能帮助你解决问题!


如果是return to caller, 那些callback加个return看看:

 if (!doc) {
            mongodb.close();
            err="父节点不存在";
          return callback(err, null);  // 这?
   }

也加了,好像是一样的啊

根据你的描述,你想要实现一个函数 User.getCC 来查询一个子节点(C),并确保在父节点存在的情况下再去查询子节点。这里的关键在于正确处理回调,并确保在所有操作完成后关闭数据库连接。

下面是简化和改进后的代码:

const mongodb = require('mongodb');

function User(user) {
    this.name = user.name;
    this.password = user.password;
    this.type = user.type;
    this.parentname = user.parentname;
}

User.getCC = function get(childname, parentname, callback) {
    mongodb.open((err, db) => {
        if (err) return callback(err);

        const collection = db.collection('users');

        // 查找父节点
        collection.findOne({ name: parentname, type: 'P' }, (err, doc) => {
            if (err) return callback(err);
            
            if (!doc) {
                return callback(new Error("父节点不存在"));
            }

            // 父节点存在,再查找子节点
            collection.findOne({ name: childname, type: 'C' }, (err, doc) => {
                if (err) return callback(err);
                
                if (doc) {
                    const user = new User(doc);
                    callback(null, user);
                } else {
                    callback(null, null);
                }
            });
        });

        // 不需要在每个回调中都关闭数据库连接,只需要在最终完成时关闭
        db.close();
    });
};

解释

  1. 错误处理:在每个操作后检查是否有错误发生,并通过回调传递错误信息。
  2. 数据库连接管理:不需要在每个 findOne 调用后都关闭数据库连接,只需在所有操作完成后关闭即可。
  3. 创建 User 对象:当找到子节点文档时,使用该文档创建一个新的 User 对象,并将其作为结果传递给回调。

这样可以避免不必要的数据库连接关闭,同时保持代码的可读性和简洁性。希望这能解决你的问题!

回到顶部