I have problems when a I call a function that calls the other function that keep calling back until a puzzle is solved or find no moves.
The thing is that I need to call a function twice but with different values.
I tried storing the values, but as soon as I call the second function wchich calls back, it overrides the values.
the most important pieces of code are here:
function splitways(){
var strsp,aa=dir,bb=xy;
if(nextRock()){
if(xy!=start){
strsp=(aa+""+bb+""+dir+""+xy)*1;
if(!(strsp in arr)){
arr[strsp]=strsp;
caller(dir,xy);
}
}else{
count++;
}
}
}
function caller(num,pos){
var aa=num,bb=pos;
splitways();
//--
dir=aa;
xy=bb;
//--
dir==1?dir=4:dir--;
splitways();
}
Notes, splitways() changes the values of dir and xy, that is why I tried to change them back and then modifing them before the second call to splitways(). But with the first call everything is erased.
I tried everything I can for 2 hours... The best shot I had was to cache them on var aa=num,bb=pos; but that didn't work.
Any ideas are appreciated
Although I'm not entirely sure what you are trying to do with your code, I think you have some of your logic mixed up:
On the first call (I assume you are calling splitways() first), you set "aa=dir" (lets only pay attention to this). When "caller()", it takes the global variable "dir", obviously. Now, in "caller()", you set "aa=num" which translates to "aa=dir". You call splitways again, which then does the exact same thing: "aa=dir". This continues constantly (AKA: until caller() is stopped being called). However, as it goes back through the execution stack, you have, in "caller()", "dir=aa". Now, you already did "aa=num", so "dir=aa" does absolutely nothing since you haven't changed the value of "dir" anywhere that has executed yet.
Eventually, the LATEST "caller()" call will execute the "dir==1?dir=4:dir--" line, but when that function finishes and the execution returns to the SECOND TO LAST "caller()" call, it resets "dir=aa", so dir is never actually changed until the VERY last call (the first "caller()" execution that happened).
If that made absolutely no sense, good. There has got to be a better way for you to do what you are trying to do. Maybe I can help with that?
Related
I created a var for a setInterval so I can stop it with clearInterval as such:
var repeat = setInterval(sayHello, 2000);
function sayHello() {
alert("Hello");
}
and here is the clearInterval:
clearInterval(repeat)
Now, in Firefox, once I ran this bit, if I want to know the value of "repeat", it returns the amount of time the interval ran. However, in Chrome, no matter how many times it ran, it always returns 1. Unless, I do the entire procedure over, it then return 2. It basically increments the instances as opposed to interval occurrences.
Anyone able to shed some light on this, how it works, and why...greatly appreciated!
All that is guaranteed is that setInterval will return a handle which can then be used by clearInterval. Other than that it is entirely up to the browser what that handle is and how it is used. Even if it seems to provide some information in one particular browser, that should not be relied on in any way as it will be subject to change.
To quote MDN:
The returned intervalID is a numeric, non-zero value which identifies the timer created by the call to setInterval(); this value can be passed to WindowOrWorkerGlobalScope.clearInterval() to cancel the timeout.
Don't expect it, or rely on it, to be anything else.
I want to modify the output of the functions (just say RANDOM examples, apologies for any code mistakes):
ng-if=!pfile.isgame
ng-if=! pfile.examplefile
-from false to true before it even has the page has any chance to drop any code on the page. How can I make it so I can append code to the page to the very beginning of the page to force every output of these particular functions to go true, on a live page?
This is definitely possible, I'm not sure where the function would be however the elements you can actually see the arguments on the page and it doesn't not look server sided at all, its just how its done. I read many articles but it many of them have not really helped me.
I am aware of Event Listener Breakpoints, its just the problem if I'm choosing the right one.
Thank you and I really appreciate it just if you can please dum down the explanation for me as even though I do understand HTML and JavaScript to an OK standard, I am still a massive beginner. This is something I always wanted to try out.
Hopefully I have understood your question correctly. There are a couple of options and the answer will depend on whether the functions are declarations or expressions.
If they are declarations, they get hoisted to the top on first pass, so that by the time your code begins execution, the function already exists and you can overwrite it early on.
If it's a function expression, you have to wait until the function expression has been created.
Example 1 (Function Declaration):
I have a function declaration on my page, which returns true if there is a remainder in the calculation, otherwise false. I execute it on page load. The output is false here:
function hasRemainder(first, second) {
return (first % second != 0);
}
console.log(hasRemainder(10, 5));
false
I have now added the Script First Statement breakpoint in DevTools, so that the debugger breaks before any script is run:
I re-open the page and the execution pauses. I now run the following code in the Console tab to override the hasRemainder function so that it always returns true:
hasRemainder = function() {
return true;
}
Finally, I click Play to continue execution. You can long click to select Long Resume, which skips breakpoints for 500ms so that you don't get caught for very single breakpoint thereafter.
true
The output this time is true as you would expect.
Example 2 (Function Expression):
We can't rely on the early breakpoint this time because the function won't exist yet. We need to add the breakpoint just after the function expression has been created.
Search for the functions using Cmd+Opt+F (Mac) or Ctrl+Shift+F (Windows).
When you are in the file with the function expression, put a breakpoint at the end of the function. When the debugger pauses, run the overriding function into the Console, and then press play to continue execution.
The Error in JavaScript internal/external file also stops the below code
For example:
var myObj = {};
myObj.other.getName = function(){
console.log('other is not defined');
};
alert('this will not show');
in above code, the alert will not come as the above code has error.
I added the same code in one file tst1.js and below this add one more file tst2.js. put alert('in tst2.js') in it. the tst2 alert come while tst1 not. it is some what related to
code compilation/interpretation.
It's much appreciated If someone explain me this behavior :)
This is the default behaviour of JavaScript. Avoid errors and the code will run normally.
Also you can handle errors with try...catch: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
All JS implementations are, AFAIK, single threaded. This means that all of your code is executed sequentially, on a single thread (logically). If this thread encounters a fatal error, it grinds to a halt. All code that comes after the point where the error occurs is ignored (the JS engine halted, no work is done anymore).
To clarify: it does not matter how many files you have. All of the JS code is stringed together into one big script, and this one script is executed sequentially (execution point starts at line 1 of the first script, and ends at the last line of the last script). Any errors in that code will cause the overall execution to grind to a halt:
//file1.js
var foo = (function()
{
console.log('This file is flawless, but pointless');
}());
//file2.js
foo();//calls previously defined function, assigned to var foo
//file3.js
fudhfsiufhi;//ERROR
//file4.js
foo();//will never get executed, because an error occurred in file3.js
Remove file3, or indeed fix the error, and everything will work as expected.
Allthough JS code is executed/evaluated sequentially, event handlers, callbacks, intervals, and timeouts might lead you to believe otherwise. Couple that with the fact that you have some control over what code is executed when, but not full control, and you get situations that, at first, seem rather counter intuitive. Consider this:
setTimeout(function()
{
massive(syntaxError) -123 + "here";
},0);//zero MS
alert('This will show');
This oddity is well documented, but it has to do with JS having a callback/handler loop, and queue. The setTimeout sets a timeout, to call the anonymous function in 0ms (immediately), but that callback is sent to the queue, which is checked periodically. Before the queue is checked (and the callback invoked), the alert will show. That's why the interval you pass to setTimeout or setInterval is not guaranteed to be exactly N milliseconds.
You can postpone a call to a method somewhat, by adding a call to the queue, like in the snippet above. But when the queue is processed, and what order the queued calls will be performed in are things you have no real say in. No say whatsoever.
It doesn't matter how many files, or how many statements that come before or after the problematic piece of code: there is no thread left to carry on.
The code you posted has a pretty clear error in it: you're assigning a property to other (a property of myObj, but this property is not defined anywhere, let alone defined as an object. Fix it by declaring properties first, before accessing them:
var myObj = {other: {}};//other is an empty object literal
myObj.other.getName = function()
{
console.log('This works');
};
alert('And the alert will show');
Your current code evalutes to:
var myObj = {};//object
var (myObj.other).getName = ...;
//evaluates to undefined
undefined.getName = ...//ERROR
undefined is a primitive value, actually signifying the absence of a value. undefined, therefore, cannot be accessed as an object, it can't be assigned properties.
Note:
This is just for completeness' sake, but JS is indeed single-threaded most of the time, but ECMAScript5 introduced Worker's which allow for some restricted form of multi-threading (without shared state, for example). Read through the MDN documentation on workers if you want to know more.
If I had the following object and prototyped functionality added on.
function Hello (input){
this.input = input
}
Hello.prototype.ajaxcall = function(id){
$.get("/ajax/method", {parameter:input}, function(data){
$("#"id).html(data);
});
}
Forgive the syntax if not completely correct but what it should be doing is taking in an element id, performing an ajax call and assigning the ajax call result to the innerHTML of the id. Will the fact that the ajaxcall function is shared across all instances of an object cause any problems with regards to what data will be assigned to which id if for example 20 object were all created together and had this function called immediately?
If this is the case, does it make sense to put asyncronous methods inside the object constructor instead?
What would happen if 20 objects would be created and the ajaxcall function would be called? Nothing much. The ajax calls would run asynchronously. When they have finished they are queued so that they run on the main thread when the current running operation on the main thread finished.
So the callback functions run all synchronous in a queue next time there's time for it. Nothing bad can happen here.
I don't understand your question about the constructor. What would that change? If you use your Hello objects they have an instance variable. This is is enclosed in the callback closure . Creating a new function doesn't change the value in another callback function.
If you use the same IDs the content could flash when the text changes and you don't know which callback would be ran last but that's the worst thing that could happen.
There should be no issue. You're calling the function 20 distinct times with 20 different ids.
Conceptually though. I'm not seeing why this is part of your object. The function does not use anything at all from the object itself.
This particular example would work. Your function makes no use of any instance variables, so it doesn't really make sense to declare it that way, but it makes even less sense to move it into the constructor. Still it will work because the id argument will not be shared between calls.
EDIT: So now that you've changed it so that it does use an instance variable you've got the syntax wrong, it needs to be
{parameter : this.input}
But aside from that it will still work. The asynchronous behaviour is not a problem for the code shown.
I have a pretty simple thing I'm doing with javascript and basically only sometimes will javascript give me a "too much recursion" error.
The code in question:
if(pageLoad===undefined){
var pageLoad=function(){};
}
var pageLoad_uniqueid_11=pageLoad;
var pageLoad=function(){
pageLoad_uniqueid_11();
pageLoad_uniqueid_12();
};
var pageLoad_uniqueid_12=function(){
alert('pageLoad');
};
$(document).ready(function(){
pageLoad();
});
(yes I know there are better way of doing this. This is difficult to change though, especially because of ASP.Net partial postbacks which aren't shown).
Anyway, when the too much recursion error happens, it continues to happen until I restart Firefox. when I restart Firefox it all works as normal again. How do I fix this?
I've also made a jsbin example
Update
Ok I've found out how to reliably reproduce it in our code, but it doesn't work for the jsbin example. If I create a new tab and go to the same page(have two tabs of the same address) and then refresh the first tab two times then I get this error consistently. We are not using any kind of session or anything else that I can think of that could cause such a problem to only occur in one tab!
Update 2
Not as reliable as I thought, but it definitely only occurs when more than one tab of the same page is open. It'll occur every few reloads of one of the tabs open
I've also updated my code to show an alert when pageLoad(the if statement) is initially undefined and when it is initially defined. Somehow, both alerts are showing up. This code is not duplicated in the rendered page and there is no way that it is being called twice. It is in a top level script element not surrounded by a function or anything! My code ends up looking like
if(pageLoad===undefined){
var pageLoad=function(){};
alert('new');
} else {
alert('old');
}
The code in question -- by itself -- should never result in an infinite recursion issue -- there is no function-statement and all the function objects are eagerly assigned to the variables. (If pageload is first undefined it will be assigned a No-Operation function, see next section.)
I suspect there is additional code/events that is triggering the behavior. One thing that may cause it is if the script/code is triggered twice during a page lifetime. The 2nd time pageload will not be undefined and will keep the original value, which if it is the function that calls the other two functions, will lead to infinite recursion.
I would recommend cleaning up the approach -- and having any issues caused by the complications just disappear ;-) What is the desired intent?
Happy coding.
This is just some additional info for other people trying to look for similar "too much recursion" errors in their code. Looks like firefox (as an example) gets too much recursion at about 6500 stack frames deep in this example: function moose(n){if(n%100 === 0)console.log(n);moose(n+1)};moose(0) . Similar examples can see depths of between 5000 and 7000. Not sure what the determining factors are, but it seems the number of parameters in the function drastically decrease the stack frame depth at which you get a "too much recursion" error. For example, this only gets to 3100:
function moose(n,m,a,s,d,fg,g,q,w,r,t,y,u,i,d){if(n%100 === 0)console.log(n);moose(n+1)};moose(0)
If you want to get around this, you can use setTimeout to schedule iterations to continue from the scheduler (which resets the stack). This obviously only works if you don't need to return something from the call:
function recurse(n) {
if(n%100 === 0)
setTimeout(function() {
recurse(n+1)
},0)
else
recurse(n+1)
}
Proper tail calls in ECMAScript 6 will solve the problem for some cases where you do need to return something from calls like this. Until then, for cases with deep recursion, the only answers are using either iteration, or the setTimeout method I mentioned.
I came across this error. The scenario in my case was different. The culprit code was something like this (which is simple concatenation recessively)
while(row)
{
string_a .= row['name'];
}
I found that JavaScript throws error on 180th recursion. Up till 179 loop, the code runs fine.
The behaviors in Safaris is exactly the same, except that the error it shows is "RangeError: Maximum call stack size exceeded." It throws this error on 180 recursion as well.
Although this is not related to function call but it might help somebody who are stuck with it.
Afaik, this error can also appear if you state a wrong parameter for your ajax request, like
$.getJSON('get.php',{cmd:"1", elem:$('#elem')},function(data) { // ... }
Which then should be
elem:$('#elem').val()
instead.
This will also cause the "too much recursion" issue:
class account {
constructor() {
this.balance = 0; // <-- property: balance
}
set balance( amount ) { // <-- set function is the same name as the property.
this.balance = amount; // <-- AND property: balance (unintended recursion here)
}
}
var acc = new account();
Using unique names is important.
Ok, so why is this happening?
In the set function it isn't actually setting the property to amount, instead it's calling the set function again because in the scope of the set function it is the same syntax for both setting the property AND calling the set function.
Because in that scope this is the same as account and (account OR this).balance = amount can both call the set function OR set the property.
The solution to this is to simply change the name of either the property or the set function in any way (and of course update the rest of the code accordingly).