我希望使用递归函数来查看mongodb中是否存在使用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 :(得分: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( ...
并将_db.User.find( ...
替换为
this.find( ...
答案 1 :(得分:0)
这是异步调用,用户名将是未定义的。
试
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
函数完成时调用它。