Files
DiceCloud/rpg-docs/lib/functions/preventLoop.js

36 lines
1.0 KiB
JavaScript

preventLoop = function(inputFunction){
var self = this;
if (!_.isFunction(inputFunction)){
throw new Meteor.Error(
"Not a function",
"preventLoop can only take a function as an argument"
);
}
//store a private array of arguments we have been given without returning
//if we try to visit the same argument twice before resolving its value
//we are in a dependency loop and need to GTFO
var visitedArgs = [];
return function(){
var result;
var hash = _.reduce(arguments, function(memo, arg) {
return memo + arg;
}, "");
//we're still evaluating this attribute, must be in a loop
if (_.contains(visitedArgs, hash)) {
console.warn("dependency loop detected");
return NaN;
} else {
//push this hash to the list of visited hashes
//we can't visit it again unless it returns first
visitedArgs.push(hash);
}
try {
result = inputFunction.apply(this, arguments);
} finally{
//this hash returns or fails, pull it from the array
visitedArgs = _.without(visitedArgs, hash);
}
return result;
};
};