我试图在MEAN堆栈中开发一个系统,该系统应该包含存储在我的数据库中的Card模型。该模型应该有两个唯一的字段,对象ID和卡片代码,它们是一个长度为8个字符的字母数字字符串。我的架构类似于:
var cardSchema = new Schema({
cod: {type: String, required: true, unique: true},
titular: {type: String, required: true, index: true},
balance: {type: Number, default: 500, min: 0, max: 500, required: true},
lastCredited: {type: Date, default: Date.now(), required: true}
})
然后我正在创建我的对象:
cards.js:post create /
router.post('/create', function(req, res) {
let card = new Card()
card.cod = Card.generateCod()
card.credit()
if (/^[a-zA-Z\s]+$/.test(req.body.titular)) {
card.titular = req.body.titular.toUpperCase()
}
else{
res.status(406).send('Invalid name for titular')
return
}
card.save(function (err, result) {
if(err) res.status(406).send(err)
else res.status(200).send(result)
})
})
我的静态方法generateCod负责将随机字符串代码分发给卡片:
cardSchema.statics.generateCod = function(){
let possible = "ABCDEFGHIJ0123456789"
let cod = ''
for (var i = 0; i < 8; i++) cod += possible.charAt(Math.floor(Math.random() * possible.length))
return cod
}
然而,为了避免重复的代码,我正在寻找一些方法来检查生成的代码是否已经被使用,然后在肯定的情况下,我将生成另一个并重复该过程,在否定的情况下我只会返回代码。我找到的解决方案是向DB发送查询,将我的代码作为参数传递并检查响应的长度,如果长度等于0,则表示代码是唯一的。到目前为止一直很好,问题是,因为我的查询与代码异步发生,我不能简单地使用while或for循环来检查代码是否是唯一的并且在它是时断开循环,导致中断不会工作,循环会永远继续下去。我实际上是这样试过的:
while(true){
for (var i = 0; i < 8; i++) cod += possible.charAt(Math.floor(Math.random() * possible.length))
Card.find({cod: cod}, function(err, result) {
if(result.length === 0) break
})
}
return cod
我也尝试过:
while(true){
for (var i = 0; i < 8; i++) cod += possible.charAt(Math.floor(Math.random() * possible.length))
Card.find({cod: cod}, function(err, result) {
if(result.length === 0) return cod
})
}
甚至:
let unique = false
while(!unique){
for (var i = 0; i < 8; i++) cod += possible.charAt(Math.floor(Math.random() * possible.length))
Card.find({cod: cod}, function(err, result) {
if(result.length === 0) unique = true
})
}
return cod
但这些似乎都不起作用,循环总是永远存在。我对节点后端比较新,我觉得我错过了什么。有谁知道我如何从异步回调中打破外部循环?或者甚至是避免重复的另一种方法?我将不胜感激任何帮助!
答案 0 :(得分:0)
Mongoose内置了对Promise
的支持,因此您可以在此处使用async/await
:
cardSchema.statics.generateCod = async function() {
let possible = "ABCDEFGHIJ0123456789";
let cod = '';
for (let i = 0; i < 8; i++) {
cod += possible.charAt(Math.floor(Math.random() * possible.length));
}
let dup = await Card.findOne({cod: cod});
if (dup) {
return new Error("Can not generate COD");
}
return cod;
}
router.post('/create', async function(req, res) {
let card = new Card()
card.cod = await Card.generateCod()
// ...
})
请注意我添加的所有async
和await
。