2014-07-02 46 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