I’m writing an api in node.js. The first webservice endpoint – /create – creates a new db entry with a randomised 6-character hash, much like a bit.ly hash.
Having done something similar in PHP, I’ve written a do..while loop which generates a random string and checks my mysql db (using node-mysql) to make sure it’s free. I’ve also got a counter in there, so I can fail after x iterations if need be.
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);
I currently only have one hash in my db (abcdef), but the loop is getting to ten and failing because it thinks each new hash is already present.
I’m pretty sure this is because of the non-blocking nature of node.js. This is obviously A Good Thing, but in my case I need the loop to block until the query has returned.
I’m pretty sure I could hack this by doing something like:
var q = db.query(...);
But I know that’s throwing away a major feature of node.js.
Is there a code pattern for this sort of need?
Yes.
No, you most certainly don’t want to do that.
Embrace the asynchronous approcach. Work with call-backs: