I want to test each element of an array until a condition is met then skip the rest. This is the code I came up with, it seems to be working but I'm not sure if its actually safe or it has unexpected side effects. Other solutions are welcomed.
let buddyAdded = false;
replicaArr = _.keys(ReplicaList);
Promise.each(replicaArr, function(replicaname) {
if (!buddyAdded) {
Player.count({
'buddyList': replicaname
}, function(err, result) {
if (err) {
} else if (result < 990) {
Player.update({
'_id': buddyObj.buddyId
}, {
'buddyList': replicaname
}, function(err) {
if (err) {
} else {
ReplicaList[replicaname].send(buddyObj);
buddyAdded = true;
// success stop here and skip all the other array elements
return;
}
});
}
});
}
});
If you're trying to enumerate the players serially one at a time and abort the iteration when you find a player with room in their buddy list that you can update the list and communicate back any errors that happen, then here's one way of doing it.
Here's how this works:
Promise.promisifyAll()
to automatically make promise returning methods for thePlayer
object so we can then use those in our control flow.Promise.mapSeries()
to iterate the array serially one at a time.Player.countAsync()
andPlayer.updateAsync()
methods so they sequence properly and return them from.mapSeries()
so it waits for them to complete before continuing the iteration to the next array element..mapSeries()
to stop it's iteration (which is what you said you wanted)..catch()
at the higher level that tests for the special rejection and turns it into a successful resolved promise. If it's some other error, then let that continue to propagate as an actual error.The code:
It may be simpler to make your own sequencer that stops when the first promise resolves to a truthy value: