我正在node.js写一个api。第一个Web服务端点 - /create
- 创建一个带有随机6字符哈希的新数据库条目,非常类似于bit.ly哈希。
在PHP中做了类似的事情后,我编写了一个do..while
循环,它生成一个随机字符串并检查我的mysql db(使用node-mysql)以确保它是免费的。我在那里也有一个计数器,所以如果需要,我可以在x
次迭代后失败。
var i = 0;
var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
var hash = null;
var success = false;
do {
// generate a random hash by shuffling the alphabet,
// joining it and getting 6 chars
hash = alphabet.sort(function(){
return 0.5 - Math.random();
}).join('').substr(0,6);
console.log(i + ': checking hash ' + hash);
// see if it exists in the db
db.query("SELECT hash FROM trips WHERE hash = " + hash, function(err, results){
if(results.length == 0) {
// the hash is free to use :)
success = true;
} else {
// the hash is already taken :(
success = false;
}
});
// increment the counter
i++;
} while(success === false && i < 10);
我目前在我的数据库(abcdef
)中只有一个哈希,但是循环达到10并且失败,因为它认为每个新哈希都已存在。
我很确定这是因为node.js的非阻塞性质。这显然是一件好事,但在我的情况下,我需要阻止循环,直到查询返回。
我很确定我可以通过做类似的事来破解这个:
var q = db.query(...);
但我知道这会丢掉node.js的一个主要功能。
是否有针对此类需求的代码模式?
答案 0 :(得分:3)
我很确定这是因为node.js的非阻塞性质。
是
这显然是一件好事,但在我的情况下,我需要阻止循环,直到查询返回。
不,你肯定不想这样做。
拥抱异步approcach。使用回拨:
function generateHash(onSuccess, onError, retryCount) {
// generate a random hash by shuffling the alphabet,
// joining it and getting 6 chars
var hash = alphabet.sort(function(){
return 0.5 - Math.random();
}).join('').substr(0,6);
// see if it exists in the db
db.query(
"SELECT hash FROM trips WHERE hash = '" + hash + "'",
function(err, results){
if (results.length == 0) {
// the hash is free to use :)
onSuccess(hash);
} else {
// the hash is already taken :(
if (retryCount > 1) {
generateHash(onSuccess, onError, retryCount - 1);
} else {
onError();
}
}
}
});
}
generateHash(
function(hash) { console.log('Success! New hash created: ' + hash); },
function() { console.log('Error! retry limit reached'); },
6
);
答案 1 :(得分:2)
var i=0;
function generateHash(callback) {
// generate a random hash by shuffling the alphabet,
// joining it and getting 6 chars
hash = alphabet.sort(function(){
return 0.5 - Math.random();
}).join('').substr(0,6);
console.log(i + ': checking hash ' + hash);
// see if it exists in the db
db.query("SELECT hash FROM trips WHERE hash = " + hash, function(err, results){
if(results.length == 0) {
// the hash is free to use :)
callback(null, hash);
} else {
// increment the counter
i++;
if (i < 10)
generateHash(callback); //another attempt
else
callback('error'); // return result
}
});
}