我目前正在学习nodejs中的Promise,现在我在处理mongoDB查询和Promise时有点陷入困境。下面是我的示例代码。
db.collection(module.exports.collectionName).find( {"$or" :[{"email":req.body.email},{"username":req.body.username}]},function(err,success){
if (err) {throw new Error("Error in accessing DB - check new user"); }
return success;
}).toArray().then(function(value){
console.log(value.length);
if (value.length == 0) {
db.collection(module.exports.collectionName).insertOne(insert,function(err,success){
if (err) {throw new Error("Error in accessing DB - insert new");}
return success;
}).then(function(value){
return resolve("Success")
}).catch(function(value){
return reject("Error happened during accessing DB, please contact the Admin inside");
});
}
return reject("Email / Username is not unique");
}).catch(function(value){
return reject("Error happened during accessing DB, please contact the Admin");
});
抱歉,代码中有很多困惑。我想问一些有关此处查询处理的问题。首先,我们如何正确处理mongodb查询中的错误,据说是这样处理的
,function(err,success){
if (err) {throw new Error("Error in accessing DB - check new user"); }
return success;
}).
一段代码?
在 toArray() 之后添加“then”解决了我之前的 promise 问题,当它到达数据库插入代码时尚未解决。但是,现在我里面有另一个数据库查询,我如何正确(再次)处理异步调用?上面的例子正确吗?
在数据库中没有重复的情况下运行此代码(意味着第一个查询返回 null)将导致返回拒绝,代码为“访问数据库期间发生错误,请联系管理员”(最后一次拒绝)。然而,数据库更新得很好,这意味着它应该到达 then 而不是 catch。查询应该已经命中中间部分的解析并返回,但代码似乎以某种方式触发了捕获。
最佳答案
问题似乎可以归结为 Promise 如何运作。看起来代码中发生了两个相关但不同的事情:
- 使用从 Mongo 返回的 Promise。
- 控制另一个 Promise(可能由该函数返回)。
我们似乎还遗漏了一个细节 - 这是在返回另一个 Promise 的函数中吗?现在让我们假设您是并且它看起来像这样:
function addNewUser(req) {
return new Promise(function(resolve, reject) {
// Insert the code from the question here.
});
}
Promise 确实只能“设置”一次。它们可以被解决
或拒绝
。但是,后续的 then() 或 catch() 调用会返回新的 Promise。这使您可以将它们链接在一起以控制应用程序的流程。同样,您可以从 Promise 处理函数中返回一个新的 Promise,以使它们按顺序工作。
因此您的 MongoDB 查询可能如下所示:
// First, run the initial query and get a Promise for that
db.collection(module.exports.collectionName).find(...)
.then(function(existingUsers) {
// Now that we found what we need, let's insert a new value
return db.collection(module.exports.collectionName).insertOne(...)
})
.then(function(addedUser) {
// Now we know that we found existing users and insert a new one
resolve(addedUser); // This resolves the Promise returned from addNewUser()
});
这可以控制 MongoDB 操作的顺序。如果您需要针对不同情况进行特殊的错误处理(例如 MongoDB 错误与用户已存在错误),您可以在需要时添加条件检查和对 catch()
的调用。例如:
// First, run the initial query and get a Promise for that
db.collection(module.exports.collectionName).find(...)
.then(function(existingUsers) {
if (existingUsers.length < 1) {
// Now that we found what we need, let's insert a new value
return db.collection(module.exports.collectionName).insertOne(...)
}
// Throw an error indicating we're in a bad place
throw new Error('A user with this name already exists!');
})
.then(function(addedUser) {
// Now we know that we found existing users and insert a new one
resolve(addedUser); // This resolves the Promise returned from addNewUser()
})
.catch(function(err) {
// This will run when an error occurs. It could be a MongoDB error, or perhaps the user-related error thrown earlier.
reject(err); // This rejects the Promise returned from addNewUser()
});
关于node.js - MongoDB Promise 和结果处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45255663/