node.js - MongoDB Promise 和结果处理

标签 node.js mongodb express promise

我目前正在学习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 如何运作。看起来代码中发生了两个相关但不同的事情:

  1. 使用从 Mongo 返回的 Promise。
  2. 控制另一个 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/

相关文章:

node.js - webpack 不支持 require.extensions。改用装载机

node.js - 使用sequelize调用存储过程

javascript - 有谁知道为什么 res.download 每次都给我的下载文件一个随机名称?

python - 使用 PyMongo,如何使用 create_index() 导入通过 index_information() 导出的索引?

javascript - 使用 'this' 引用与meteor.template.rendered

node.js - 为什么我的自定义错误对象会被 Express 路由器转换为字符串?

javascript - 如何使用 {variableName} 创建变量/const

regex - Node js Express 框架 - 正则表达式不起作用

javascript - Node.js "write after end"错误

javascript - 使用 mongodb/mongoose 有条件地将 5-20k 文档的输入批处理处理为包含多达一百万个文档的集合的有效方法是什么?