2014-07-02 43 views
1

我有一个MongoDB数据库设置了一些具有唯一代码(而不是主键)的对象。 我还应该注意到,我使用的是NodeJS,并且此代码位于我的server.js中以连接到MongoDB数据库。while循环来检查自定义ID的唯一性

要生成一个新的代码,我随机生成一个,我想检查它是否已经存在。如果没有,那么我们使用它没有问题,但如果它已经存在,我想生成另一个代码并再次检查它。这是我用它来检查,如果该ID已经存在的代码:

function createPartyId(callback) { 
    var min = 10000, max = 99999; 
    var partyId = -1, count = -1; 
    async.whilst(
     function() { return count != 0; }, 
     function (callback) { 
      partyId = min + Math.floor(Math.random() * (max - min + 1)); 
      partyId = 88888; 
      getPartyIdCount(partyId, function(num) { 
       count = num; 
      }); 
     }, 
     function (err) { 

     } 
    ); 
} 

function getPartyIdCount(partyId, callback) { 
    count = -1; 
    db.db_name.find({id: partyId}, function(err, records) { 
     if(err) { 
      console.log("There was an error executing the database query."); 
      callback(count); 
     } 
     count = records.length; 
     callback(count); 
    }); 
} 
+0

您能否提供您的getExistingCount()的实际实现? – sreisman

+0

我用代码 – appel

+0

更新了我的主帖我认为find函数返回undefined时可能会出错 – appel

回答

2

(从上面扩大我的评论)

问题是createPartyId是一个异步函数,但是你要同步返回值。这是行不通的。一旦触及异步操作,其余的调用堆栈也必须异步。

你不包括的呼唤这个代码,但我相信你希望它是这样的:

var partyId = createPartyId(); 
// do stuff... 

这是行不通的。试试这个:(我也采取了始终返回错误的回调函数的第一个参数的默认node.js的约定)

function createPartyId(callback) { 
    var min = 10000, max = 99999; 
    var partyId = -1, count = -1; 
    async.whilst(
     function() { return (count == 0); }, 
     function (callback) { 
      partyId = min + Math.floor(Math.random() * (max - min + 1)); 
      partyId = 88888; 
      getPartyIdCount(partyId, function(err, num) { 
       if (!err) { 
        count = num; 
       } 
       callback(err); 
      }); 
     }, 
     function (err) { 
      // this is called when the loop ends, error or not 
      // Invoke outer callback to return the result 
      callback(err, count); 
     } 
    ); 
} 

function getPartyIdCount(partyId, callback) { 
    count = -1; 
    db.db_name.find({id: partyId}, function(err, records) { 
     if(err) { 
      console.log("There was an error executing the database query."); 
      callback(err); 
     } 
     count = records.length; 
     callback(null, count); 
    }); 
} 

因此,要使用这个,你会怎么做:

getPartyId(function (err, num) { 
    if (err) { return aughItFellOver(err); } 

    // do stuff 
}); 
+1

是的!非常感谢你,对于具有所有这些异步回调的第一个定时器来说非常棘手。你是最好的! – appel

+0

@Chris Tavares它工作完美的人:)感谢您的回答+1 –

3

首先,有没有你不使用一个简单的数字递增序列什么特别的原因?这种类型的代码很容易效率低下,产生的数字越多,碰撞的机会就越大,这意味着您将花费更多时间为数据生成ID,而不是处理其余的处理。不是一个好主意。

但我仍然可以告诉你哪里出了问题。

好吧,所以getPartyIdCount()将永远,永远,永远不会失败,返回未定义(或,基本上什么都没有)。

您的mongo调用会在回调中处理返回值,并且该回调函数不会将其值赋给任何内容,因此return records.length只会变成虚无。

你混淆了createPartyId(),它似乎你想同步运行,你的mongo调用,它必须异步运行。

return始终与包含function最近去,所以在这种情况下,去与function(err, records),不function getPartyIdCount(partyId)

+0

我不想添加一个简单的计数器,因为我需要它是半随机的。如果用户得到的代码是11111,那么他可以猜出11112或11110.我已经在主帖中更新了代码,但它仍然无效。 – appel

+0

我显然不知道你的应用程序,但是...什么?无论如何,他可以猜测11112,即使它们是随机分配的,它也可能只是一个有效的ID。如果你需要它实际上是不可测的,那么你需要一个随机字符串,而不仅仅是一个随机数。如果你需要它是真正无法猜测的,你需要使用CSPRNG。但更可能的是,您需要构建应用程序,以便猜测其他ID不会暴露弱点。 – Jason