【问题标题】:Execute my functions Asynchronously in NodeJS在 NodeJS 中异步执行我的函数
【发布时间】:2017-10-23 07:49:58
【问题描述】:

我是 NodeJS 的新手。我知道有很多关于异步 NodeJS 的问题,但我找不到我正在寻找的确切内容。

我的问题是: 我想检查用户名和电子邮件是否已经存在于我的数据库中。用户名和电子邮件的两个独立功能。另一个功能是将数据存储到数据库中。

我不知道如何使用异步 NodeJS 模式来做到这一点。

User.js(猫鼬模式)

const mongoose = require('mongoose');
var userSchema = mongoose.Schema({
    name: String,
    username: { type: String, required: true, unique: true },
    password: { type: String, required: true },
    email: { type: String, required: true, unique: true},
    aiub_id: String,    
});
const Users = module.exports = mongoose.model('User', userSchema);

module.exports.addUser = function (user, callback) {
    user.save(callback);
}
module.exports.usernameExist = function (givenUsername, callback) {
    Users.find({ username: givenUsername }, callback);
}
module.exports.emailExist = function (givenEmail, callback) {
    Users.find({ username: givenEmail}, callback);
}

index.js(路由)

route.post('/signup', function(req, res){
// GRAB USER INFO FROM HTML FORM
var newUser = new User({
    name : req.body.tfullName,
    username : req.body.tusername,
    password : req.body.tpassword,      
    email : req.body.temail,
    aiub_id : req.body.tuserID
});

// This block send 200 if username doesn't exist
User.usernameExist(newUser.username, function (err, result){
    if(err){
        throw err;
    }
    if(result.length <= 0){
        res.send({status : 200 });
    }else{
        res.send({status : 100 });
    }
});

});

请帮我解决这个问题,如果这听起来很愚蠢,请原谅。

【问题讨论】:

  • 您可以在此处使用$or 运行单个查询。这样您就无需担心链接回调,而且它的开销 更少且速度更快。或者,您甚至可以接受返回的“重复错误”相当于确实存在一个唯一属性这一事实,然后要求用户再试一次。

标签: javascript node.js mongodb asynchronous


【解决方案1】:

在另一个函数的回调中调用一个函数,

// Check if username doesn't exist
User.usernameExist(newUser.username, function (err, result){
    if(err){
        throw err;
    }
    if(result.length <= 0){

        //check if email doesn't exist
        User.emailExist (newUser.email, function(err, result){
            if(result.length<=0){

                //save user
                User.addUser(newUser, (err, result)=>{
                     if(!err){
                         res.send({status : 200 });
                     }else{
                         res.send({status : 100 });
                     }
                })  
            }
        }
    }
});

比起回调,人们更喜欢 Promise,要使用 Promise,你必须从你的函数中返回一个 Promise。使用 Promise 代码更容易阅读,因此请仔细研究。

【讨论】:

  • 这是一种有效的异步方式吗?对不起,如果这听起来很愚蠢!
  • 这没有利用异步的力量。
  • @MikaelLennholm 你可以为这个问题提供任何替代方法吗?
  • @BigGuy 好吧根据你的问题,先检查用户名,然后发送电子邮件,然后保存用户,这是这样做的,在以前函数的回调中依次调用函数.比这更好的解决方案是使用 Promise。
  • @anuragasaurus 您对问题的描述不是 OP 所要求的。 “根据您的问题,首先检查用户名,然后发送电子邮件,然后保存用户” 不是 OP 想要的,OP 想要检查用户名和电子邮件 并行 b>,然后在两个结果都可用时采取行动。承诺确实是解决方案。
【解决方案2】:

使用Promises。

首先我建议你改变你的函数以返回 Promise 而不是回调:

function userExists(parameters) {
  return new Promise((resolve, reject) =>
    Users.find(parameters, (err, result) => {
      if(err){
        reject(err);
      } else {
        resolve(result.length <= 0);
      }
    })
  );
}

module.exports.usernameExist = function (givenUsername) {
  return userExists({ username: givenUsername });
}

module.exports.emailExist = function (givenEmail) {
  return userExists({ email: givenEmail });
}

然后,您将从对这些函数的并行调用返回的 Promise 包装在 Promise.all 中,它会返回一个新的 Promise,当所有包装的 Promise 都得到解决时,该 Promise 就会解决,然后您在那里做您的事情:

Promise.all([
  User.usernameExist(newUser.username),
  User.emailExist(newUser.email)
]).then((results) => {
  // results[0] contains the result from User.usernameExist
  // results[1] contains the result from User.emailExist
});

如果您不想更改 User 模块中的函数,则可以将这些函数的调用封装在 index.js 文件中的 Promises 中。

【讨论】:

  • 感谢您的回答。这很有可读性。让我看看它是否适合我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-14
  • 2022-08-19
  • 2020-07-16
  • 2014-11-27
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多