2017-01-03 48 views
0

我想使用函数递归来查看用户名是否存在于mongodb中,并且mongoose和nodejs。未定义的返回值mongoose/nodejs递归函数

我使用回调,但我不明白为什么我的函数返回未定义的结果。你可以帮帮我吗 ?

感谢;)

var mongoose = require('mongoose'); 
var debug = require('debug')('gc:model:User'); 

var UserSchema = new Schema({ 

    username: {type: String, required: true, trim: true, index: {unique: true, dropDups: true}}, 
    email: {type: String, trim: true}, 

    role: {type: String, required: true, default: 'user'}, 

}); 

generateUsername = function (username, number) { 
    'use strict'; 

    var i = 0; 
    var usernames = []; 
    usernames.push(username); 

    while (i < number) { 
    var count = parseInt(usernames[i].substr(-1)); 
    if (count >= 0) { 
     count += 1; 
    } else { 
     count = 0; 
    } 
    usernames.push(usernames[i].substring(0, count === 0 ?  usernames[i].length : usernames[i].length - 1) + count); 
    i++; 
    } 

    return usernames; 
}; 


findUniqueUsername = function (usernames, cb) { 
    'use strict'; 
    if (usernames.length === 0) { 
    return cb(null); 
    } 

    // If one of the username is undefined, go the next one 
    if (typeof usernames[0] === 'undefined') { 
    usernames.shift(); 
    findUniqueUsername(usernames); 
    } 

    _db.User.findOne({'username': usernames[0]}).exec(function (err, user) { 
    if (err) return cb(err); 

    if (user) { 
     debug('Bu ! => ', usernames[0]); 
     usernames.shift(); 
     findUniqueUsername(usernames); 
    } 
    else { 
     debug('GooD ! => ', usernames[0]); // Value OK i have 
     return usernames[0]; // Value Not OK undefined :(
    } 
    }); 

}; 

var namestart = "jobs"; 

var usernameTries = generateUsername(namestart, 100); 
var username = findUniqueUsername(usernameTries); // is undefined 
+0

可能重复[如何从异步调用返回响应?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-调用) – nem035

+0

哪个函数调用返回undefined?控制台中是否有错误? – Cruiser

+0

可能是'findUniqueUsername',它包含一个异步调用,但OP试图以同步的方式从它读取一个结果,即'var username = findUniqueUsername(usernameTries);'。上述建议很可能应该被封闭 – nem035

回答

0

变量username将保持不确定的,因为你是预成型的异步调用。

如果您通过生成100个用户名开始,您可以查询所有这些用户名,然后筛选出不存在的用户名。通过再次调用findUniqueUsernames并传递回调,您仍然可以使用此递归。

'use strict'; 

const mongoose = require('mongoose'); 

let UserSchema = new Schema({ 

    username: { 
    type: String, 
    required: true, 
    trim: true, 
    index: { 
     unique: true, 
     dropDups: true} 
    }, 
    email: { 
    type: String, 
    trim: true 
    }, 

    role: { 
    type: String, 
    required: true, 
    default: 'user' 
    }, 

}); 

var generateUsernames = function (username, number) { 

    let usernames = new Array(number - 1) 
    .fill(username) 
    .map((username, index) => username + index); 

    usernames.unshift(username); 

    return usernames; 
}; 

var findUniqueUsernames = function (usernames, callback) { 
    if (usernames.length === 0) return callback(null, null); 

    _db.User.find({ 
    username: { 
     $in: usernames 
    } 
    }) 
    .select('username') 
    .exec((err, results) => { 
    if (err) return callback(err, null); 
    else { 
     let existingUsernames = results.map(r => r.username); 
     let uniqueUsernames = usernames 
     .filter(username => existingUsernames.indexOf(username) < 0); 
     return callback(null, uniqueUsernames); 
    // as an alternative, you could check here, 
    // if uniqueUsernames.length === 0 
    // and use findUniqueUsernames recursive by passing the same callback again 
    // return findUniqueUsernames(newSetOfPossibleUsernames, callback) 
    } 
    }); 
}; 

var namestart = 'jobs'; 

var usernameTries = generateUsernames(namestart, 100); 

findUniqueUsernames(usernameTries, (err, uniqueUsernames) => { 
    if (err) { 
    console.log(err); 
    } else { 
    console.log(uniqueUsernames); 
    } 
}); 

在更mongoosie的世界,我会做findUniqueUsernames至少UserSchema的静态方法:

UserSchema.statics.findUniqueUsernames = function(... 

this.find(... 
0

更换_db.User.find(...这是异步调用和用户名未定义。

尝试

else { 
    debug('GooD ! => ', usernames[0]); // Value OK i have 
    return usernames[0]; // Value Not OK undefined :(
} 

变化

else { 
    debug('GooD ! => ', usernames[0]); 
    return cb(null, usernames[0]); 
} 

var username = findUniqueUsername(usernameTries); 

变化

var username; 
findUniqueUsername(usernameTries, function(err, data){ 
    username = data; 
}); 

回调函数是一段作为参数传递给其他代码的可执行代码,预计会在某个方便的时间回调(执行)参数。调用可以像在同步回调中​​一样立即执行,也可以在稍后发生,就像在异步回调中一样。 (维基百科)。 在你的情况下,当findUniqueUsername函数完成时调用它。