admin管理员组文章数量:1410674
Based off suggestions from a previous question Illegal break statement (Node.js) , I implemented async.whilst()
, but it is not iterating more than once.
I am trying to find a unique ID, by incrementing a number at the end of an ID, and querying Mongo to see if that ID exists. If it doesn't exist, the unique ID is found. It is only looping once, instead of until a unique is found. What is wrong?
The code:
var uniqueNumber = 1;
var newUnique;
async.whilst(
function () {
var uniqueNum_string = uniqueNumber.toString();
newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique}, function(err, data){
if (data){
console.log('entry found!');
return;
}
else {
console.log('entry not found!');
}
});
},
function (callback) {
uniqueNumber++;
},
function (err) {
saveLandmark(newUnique);
}
);
Based off suggestions from a previous question Illegal break statement (Node.js) , I implemented async.whilst()
, but it is not iterating more than once.
I am trying to find a unique ID, by incrementing a number at the end of an ID, and querying Mongo to see if that ID exists. If it doesn't exist, the unique ID is found. It is only looping once, instead of until a unique is found. What is wrong?
The code:
var uniqueNumber = 1;
var newUnique;
async.whilst(
function () {
var uniqueNum_string = uniqueNumber.toString();
newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique}, function(err, data){
if (data){
console.log('entry found!');
return;
}
else {
console.log('entry not found!');
}
});
},
function (callback) {
uniqueNumber++;
},
function (err) {
saveLandmark(newUnique);
}
);
Share
Improve this question
edited May 23, 2017 at 12:15
CommunityBot
11 silver badge
asked Aug 2, 2013 at 20:20
alyxalyx
2,7436 gold badges45 silver badges69 bronze badges
5
- I believe you have to return true in the "entry not found" else statement for it to loop again. – Hector Correa Commented Aug 2, 2013 at 20:26
- 5 You can't really use whilst since the test function is supposed to be synchronous. Also you have to actually call the callback in the iterator. – Andreas Hultgren Commented Aug 2, 2013 at 20:29
- Good point @AndreasHultgren. I totally overlooked that. – Hector Correa Commented Aug 2, 2013 at 20:33
- How should iterate through this then? @AndreasHultgren – alyx Commented Aug 2, 2013 at 20:34
- @jrbaldwinn just a sec I'll post an answer instead – Andreas Hultgren Commented Aug 2, 2013 at 20:40
2 Answers
Reset to default 7I couldn't actually find a good async function suited for this task, so I hacked something together using async.forever(). That function will keep running until you callback an "error", which is what you want to do.
var uniqueNumber = 1;
var newUnique;
async.forever(function (next) {
var uniqueNum_string = uniqueNumber.toString();
newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique}, function(err, data){
if (data){
console.log('entry found!');
uniqueNumber++;
next();
}
else {
console.log('entry not found!');
next('unique!'); // This is where the looping is stopped
}
});
},
function () {
saveLandmark(newUnique);
});
Regarding what you're trying to solve, it seems to me you want to insert a new document with a unique id. If that is the case and you're gonna do it often, I would say this is a highly inefficient approach. If you have a thousand documents in the database you would do a thousand pletely meaningless requests to the database before you even get close to a unique id.
A better approach would be to get the first document from the collection sorted descending by id (eg the highest id). Then increase that id by one and try to insert until it's not rejected. Because even if you find a unique id, by the time you save the document another insert might have been made from another client or another instance (in case of load-balancing). This may or might not be a problem in your case, I don't know enough about your app, I just thought you should be aware of the drawbacks with your current approach and my answer.
SOmething like this? I didn't test it because I don't know what DB module you're using, but the logic should be obvious.
function searchNubmersForResults(firstNumber, callback) {
//place other variables here, and you can collect the results within the closure, and send them as arguments to your callback
function testNumber(uniqueNumber) {
var uniqueNum_string = uniqueNumber.toString();
newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique}, function(err, data){
if (data){
console.log('entry found!');
callback(data);//We're done, use the callback on the data
} else {
console.log('entry not found!');
testNumber(uniqueNumber++);//Launch the next test
}
});
}
testNumber(firstNumber);//Laucn the first test
}
searchNubmersForResults(0, function(data) {
console.log('You have data now: ' + data);
});
本文标签: javascriptNodejsAsync Whilst loop not iteratingStack Overflow
版权声明:本文标题:javascript - Node.js - Async Whilst loop not iterating - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744981808a2635861.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论