2017-05-23 9 views
0

私はNodeJSを初めて使用しています。私は、非同期NodeJSに関する多くの質問があることを知っていますが、私が探しているものを正確に見つけることができませんでした。私の機能をNodeJSで非同期に実行

私の問題は: ユーザー名と電子メールが既に存在するかどうかをデータベースから確認したいのですが。ユーザー名と電子メールの2つの機能別の機能は、データベースにデータを格納する機能です。

非同期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 }); 
    } 
}); 

}); 

私はこれを解決するために助けてくださいと、それは愚かに聞こえる場合はご容赦ください。

+1

ここで '$ or'を使用して1つのクエリを実行できます。次に、コールバックの連鎖を心配する必要はありません。**オーバーヘッドが少なく、高速です。あるいは、重複エラーが実際に存在するという事実が返されたことを受け入れるだけで、ユーザーに再度試してもらうように促すこともできます。 –

答えて

2

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.all、これらの機能にparallellの呼び出しから返された約束を包みますすべてのラップの約束が解決した後、あなたはそこに自分のものを行います:

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モジュールであなたの関数を変更したくない場合は、あなたがそれらのFUNCへの呼び出しをラップすることができますその代わりにindex.jsファイルにPromiseがあります。

+0

あなたの答えをありがとう。これは非常に読みやすいです。それが私のために働くかどうかをチェックさせてください。 –

0

ただ、他の、

// 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 }); 
        } 
       }) 
      } 
     } 
    } 
}); 

人々のコールバックで1つの関数を呼び出すには、あなたがあなたの関数からの約束を返す必要があるでしょう約束を使用するように、コールバックに約束を好みます。約束すれば、コードは読みやすくなります。

+0

これは有効な非同期方法ですか?申し訳ありませんが、それは愚かな音だ! –

+1

これは、非同期の力を活用していません。 –

+0

@MikaelLennholmこの問題の代替方法はありますか? – nrgwsth