is there anyway to detect recursive method in javascript/jQuery? - javascript

I am working on small part of calculation code. I need to identify whenever recursive occur in javascript/jQuery and i need to terminate that recursive.
Is there any api to support this in javascript/jQuery?

You could implement your own recursive protection. There is nothing built into jQuery that would natively support preventing recursion.
function myFunc(arg) {
// if this function already executing and this is recursive call
// then just return (don't allow recursive call)
if (myFunc.in) {
return;
}
// set flag that we're in this function
myFunc.in = true;
// put your function's code here
// clear flag that we're in this function
myFunc.in = false;
}
myFunc.in = false;
You could also turn the boolean into a counter and allow recursion only up to a certain number of levels.
FYI, because JS is single threaded, this should only be an issue that might need protection if your function takes some sort of callback from code that isn't yours. If it's all your own code, then you should just make sure your own code won't cause this sort of problem.
Here's a little more foolproof version that protects the counter in a closure so it can't be manipulated outside the function:
var myFunc = (function() {
var inCntr = 0;
return function(args) {
// protect against recursion
if (inCntr !== 0) {
return;
}
++inCntr;
try {
// put your function's code here
} finally {
--inCntr;
}
}
})();
Note: this uses a try/finally block so even if your code or any code you call throws an exception the counter is still cleared (so it never gets stuck).

Another dodgy trick. If you use something like .bind(this) for recursion or if you use arrow function, it won't work.
boom();
function boom () {
if(arguments.callee === arguments.callee.caller) {
console.log('no recursion will happen');
return;
}
boom();
}
Simple solution could be a flag in a parameter
boom2();
function boom2 (calledRecursively) {
if(calledRecursively) {
console.log('no recursion will happen');
return;
}
boom2(true);
}

Related

How to monkey patch a recursive function

I'm using a library (playcanvas) that exposes a function clone() that is called recursively for all the nodes in a hierarchy.
If I monkey patch the function to execute some additional code, this will be executed multiple times.
Instead, I need to execute my code at the end of the whole recursive calls, but I can't find a way to do it.
pc.Entity.prototype.clone = function() {
... some code
// then for each child it calls itself
}
If I try this way I get "my stuff" executed multiple times.
pc.Entity.prototype.cloneOriginal = pc.Entity.prototype.clone;
pc.Entity.prototype.clone = function() {
var c = this.cloneOriginal();
// do my stuff
return c;
}
I need to "override" the clone method so that after all its recursive calls, I can execute my code.
You can achieve that by temporarily restoring the original function before launching it. And when it is finished, you set your trap again, and perform your post processing:
const orig_clone = pc.Entity.prototype.clone; // Save original clone
// Set trap:
pc.Entity.prototype.clone = function patched_clone(...args) {
pc.Entity.prototype.clone = orig_clone; // Restore original function
let result = this.clone(...args); // Execute it
// All is done, including recursion.
pc.Entity.prototype.clone = patched_clone; // Set trap again
// Your code comes here
console.log('post processing');
return result;
}
I'd still go with a simple flag to determine wether I'm inside a recursion or not.
//no need to store that function on the prototype itself
const cloneOriginal = pc.Entity.prototype.clone;
let inRecursion = false;
pc.Entity.prototype.clone = function() {
//just pass through the call to the original function.
if(inRecursion)
return cloneOriginal.call(this);
inRecursion = true;
var c = cloneOriginal.call(this);
inRecursion = false;
// do my stuff
return c;
}
inRecursion is a flag, specific for this single implementation. Maybe you want to wrap this code in a block or an iife to ensure that the variables are not accessible from outside of your clone-method.
could you point me to some more info about the optimization you are speaking about. What should I google?
You'll find most about v8 optimizations on google, but most modern browsers do similar stuff. I just googled and came across this article Performance Tips for JavaScript in V8. It's a bit older, but I think it's a good point to start getting an understanding on the kind of optimizations that JS engines do to your code to make it faster.
But as the article it mentions, don't loose yourself in (pointless) optimizations.

addEventListener not working correctly

So I have a div which has an EventListener on it which works fine. But I want the EventListener to only be triggered at certain points, which is why I added an if statement to it.
I was under the impression that you can change global variables from functions the way my code is below yet this doesn't seem to work at all. I have tried changing the variable within the function by way of window.clickDisable = false; but that does not work either. The relevant parts of the code are below, does anybody know why this is not working? Thanks.
var clickDisable = true;
if (clickDisable == false) {
document.getElementById("fight")
var fightMenu = fight.addEventListener("click", fightMenuFunction)
}
function fightMenuFunction () {
}
setTimeout(introAnimation, 7000)
function introAnimation() {
clickDisable = false;
}
There are a handful of problems with your code:
I think the best approach is to put your if statement within the body of the function. You want the body of your function to run only if the timer has elapsed, rather than the event to be bound only if the timer has elapsed.
Also, your document.getElementById was not being used. You were instead benefiting from the fact that element ids are automatically interpreted as global variables, which you can do, as I have done below, but is probably not a best practice.
var clickDisable = true;
function fightMenuFunction () {
if(!clickDisable){
console.log('This is the function running.')
}
}
fight.addEventListener("click", fightMenuFunction)
window.setTimeout(introAnimation, 7000)
function introAnimation() {
clickDisable = false;
}
<button id="fight">Fight</button>

Cleaner way to see if function is defined

Is there an easier way to check if a javascript function has already been called and is active besides what I have below, or is what I have below already optimized...
var isDefined = function(func) {
if(func !== undefined)
{
return true;
}
else
{
return false;
}
}
JavaScript does nothing to retain memory of a function having already been called. You can put a Boolean var flag outside of it, set it to true inside, and ensure its scope doesn't leak by putting it inside an IIFE, which may give you what you want.
If what you're doing is related to click/event listening, you may want to use something like JQuery's $.once(), which adds an event listener that removes itself after occurring once.
var isDefined = function(func) {
return (func !== undefined);
}

Alternative to throwing/catching errors with async code?

I'm used to throwing an instance of some error class and having them be caught somewhere down the line in the app, to account for user error.
An example might be validating the username:
function validateUsername (username) {
if (!/^[a-z0-9_-]{3,15}$/.test(username)) {
throw new ValidationError('Please enter 3-15 letters, digits, -, and/or _.');
}
}
$('#username').blur(function () {
try {
validateUsername($(this).val());
} catch (x) {
$('<p></p>').addClass('error').text(x).insertAfter(this);
}
});
But now I'm realizing that I can't use these same practices for asynchronous calls. For example:
function checkUsernameAvailability (username) {
$.get('/users/' + username).done(function () {
// Done = user returned; therefore, username is unavailable
// But I can't catch this error without resorting to something gross
// like window.onerror
throw new ValidationError('The username you entered is already in use.');
});
}
I could make checkUsernameAvailability accept a callback and/or return a promise and have it execute said callback with the availability of the username.
$('#username').blur(function () {
checkUsernameAvailability(username, function (available) {
!available && alert('The username you entered is already in use.');
});
});
But part of what makes exceptions so powerful is that they can bubble up the stack until they get caught, whereas if I had another function that called another function that called checkUsernameAvailability, I'd need to pass the result of this callback manually all the way until I get to the place where I want to handle it.
What are some of the alternative methods for passing errors up the stack? I can think of some of these, but none of them are as clean as native exceptions:
Passing a flag, or the ValidationError instance, to a callback (Node.js approach could work too, passing an error or null as the first argument, and the data as the second); but then, if I don't want to handle it at that point in the stack, I need to pass the error up manually
Or passing 2 callbacks to the checkUsernameAvailability function, a success callback and an error callback; this seems to have the same drawbacks as the previous point
Triggering a "ValidationError" event so I can listen anywhere, but make sure to return false; in the handler so it doesn't execute higher in the stack; however, this pollutes the event namespace and could make it unclear as to which event listener will be executed first; plus, it's difficult to trace an event to its origin using the console
in principal it is like this
function Exception (errcode) {
this.code = errcode;
}
...
try {
...
throw new Exception('alpha');
...
} catch (e) {
if (e.code === {something}) {
}
}
If it helps, I recently took the first release of the Rogue game written for UNIX in C and rewrote it for javascript to work in a browser. I used a technic called continuation to be able to wait for key entry by the user because in javascript the are no interrupts.
So I would have a piece of code like this:
void function f() {
// ... first part
ch = getchar();
// ... second part
}
that would be transformed in
function f() {
// ... first part
var ch = getchar(f_cont1);
return;
// the execution stops here
function f_cont1 () {
// ... second part
}
}
the continuation is then stored to be reuse on a keypressed event. With closures everything would be restarted where it stoped.

Is there a way to check for if certain conditions are true on the second call of a function?

So I want to call a function
myfunction();
I want to be able to have my code call it once and be fine but if my code calls it a second time, I want to check to see if certain conditions are true and if they are, I want the function to not run. If these conditions aren't true, then I want the function to run as usual. I just want to know if something specific is true only for a second call to the function and not allow my function to run again until those conditions aren't true anymore.
if(condition) {
//don't run function code for as long as this is true.
}
else{
//business as usual, run the code
}
I want to do this always on the second call to the function. So first function call, no checking. On a second call, check. On a 3rd call no checking, on the 4th call check etc. Basically, every other call to the function, check to see if certain conditions are true
and if they are, don't run the function code. I would very much appreciate your response.
This is easy enough. Since what you're looking for is basically a function that modifies its behavior according to some internal state, it's an ideal application for objects:
var o = {
calls: 0,
fn: function(){
if(++this.calls%2){
console.log('odd call');
} else {
console.log('even call');
}
}
}
If you absolutely must have a function only (no object), you can use an immediately-invoked function expression (IIFE) to return a function:
var fn = (function(){
var calls = 0;
return function(){
if(++calls%2){
console.log('odd call');
} else {
console.log('even call');
}
}
})();
This has the advantage of encapsulating the calls variable: that can't be accessed or tampered without outside of the function.
As a cautionary note, what this achieves is called a "side effect": that is, the behavior of the function can no longer be predicted without understanding the details of the function. I'm not going to be dogmatic and say side effects are always bad, but you do have to be careful with them: make sure they make sense, and that your documentation is clear about what's happening.
you'd need an index variable outside of the function scope.
something like this:
var index = 0;
function myFunction() {
// TRUE on every second call
if (++index % 2 === 0) {
if (condition) {
// ....
} else {
// ...
}
}
// ....
}
You could use a closure: instead of
function f(x, y, z) {
... normal processing ...
}
create a closure that every other call will do the check
var f = (function(){
var do_check = true;
return function(x, y, z){
do_check = !do_check;
if (do_check && ... check ...) {
... special handling ...
} else {
... normal processing ...
};
})();
As others said however I'd say that keeping this behavior hidden inside the function seems a bad idea. Probably a better solution is just externalize (and document) the state.
This is not an answer to your question.
For sure there will be answers that tell you how to do this, but I'd argue that "The only winning move is not to play."
Having functions that behave differently between calls make will make your software very hard to work with (maintain, test, debug, reason about).
Should there be a reason for needing the function to behave differently between calls, make it about the state of the system, not purely about the function itself.
Agree with pkyeck, but why increase a var.
var checkCall = 1;
function myfunction(){
if(checkCall){
alert('true: so no code will run');
checkCall = 0;
} else {
alert('run the code');
checkCall = 1;
}
}

Categories