Different Result when function is called inside a function - javascript

I have the following JS Code which check a webpage to see if new Keys are posted on it at regular interval. Now the problem is that:
When start() is directly called from Dev Console (F12), the results are Correct and when my Function $(document).ready calls it the results are Wrong, and yes i have 100 times confirmed that no content on page is changing.
I was just curious to see if the vars are getting out of sync, so i called start() 2 times in $(document).ready, and still the wrong results but when i called satrt() from F12 (after calling it 20 times from $(document).ready, i got Correct Result.
I have confirmed that all events are waiting for each other to finsih (maybe called synchronous) and its not true that any single statement is running in a different thread.
Then how its possible that if F12 calls it, then its Correct and if $(document).ready calls it then its wrong.
A intresting point to be noted:
When i didn't had $(document).ready in my code, i called wow() from start() which also gave me wrong result, but F12 gives Correct.
Now that i have $(document).ready , if i call start() from it which inturn calls wow() gives me wrong result, but now if i call start() from my console, it gives me right result!
What i acually want to do in simpler form:
wait for page to finish loading
Call wow()
wait for wow() to finish
Reload Page
Same process continues in infinite loop.
Humble Thanks for any help, this has been wating my time for almost 5-6 hours!
JS Code : http://pastebin.com/9UJYdepU
EDIT:
Correct output:
a.js:136 Started
a.js:33 Called Wow
a.js:83 ---------------------KEY 7.0----------------
a.js:83 ---------------------KEY 7.1----------------
a.js:83 ---------------------KEY 7.2----------------
a.js:102 LAST used keys : Saab,Volvo,BMW,4E69G-8GNG4-JCZ4Z,H63HQ-VHWPX-ZCJ8J,FKZGK-MXL5C-P2YTE,4E69G-xxxxxx-JCZ4Z,4E69G-AAAxx-JCZ4Z,4E69G-AAAxx-JasasCZ4Z,4E69G-AAAxx-JasaaaasCZ4Z
a.js:140 WOWO DONW
Wrong Output:
Started
a.js:33 Called Wow
a.js:102 LAST used keys : Saab,Volvo,BMW,4E69G-8GNG4-JCZ4Z,H63HQ-VHWPX-ZCJ8J,FKZGK-MXL5C-P2YTE,4E69G-xxxxxx-JCZ4Z,4E69G-AAAxx-JCZ4Z,4E69G-AAAxx-JasasCZ4Z,4E69G-AAAxx-JasaaaasCZ4Z
a.js:140 WOWO DONW
document.getElementsByTagName("p"); Gives: http://pastebin.com/JXQ9483N
localStorage.getItem("usedp") Gives Saab,Volvo,BMW,4E69G-8GNG4-JCZ4Z,H63HQ-VHWPX-ZCJ8J,FKZGK-MXL5C-P2YTE,4E69G-xxxxxx-JCZ4Z,4E69G-AAAxx-JCZ4Z,4E69G-AAAxx-JasasCZ4Z,4E69G-AAAxx-JasaaaasCZ4Z

Finally i solved it! This was all becuase of evil Jquery (Sorry, if i hurt you).
$(document).ready was triggering when the page started loading not when it has finsihed loading, my alternate solution is:
var myVar = setInterval(function(){ chk() }, 500);
function chk(){
if(document.readyState=="complete"){
clearInterval(myVar);
startt();
}
}

Related

What is inside Callback queue (debugger)?

I would like to know how is it possible to know the content of the callback queue.
For example, if you consider the following Javascript code :
<script>
console.clear();
setTimeout( function () {console.log("Hello ")},5000);
console.log("What is inside Callback Queue ? ");
</script>
Is there a mean to print the content of the callback queue to the console ?
If not possible in such that way, is it possible with a debugger by adding a break point to the line console.log("What is inside ...?"); (I tried with Firefox debugger but I did not manage to do it)
Or another solution ?
Thanks for answer.
The performance tab of the browser's developer tools contains all the informations needed. Do the following:
Filter markers : function call (only to avoid a lot of
informations)
Start Recording
Reload (CTRL + R)
Stop Recording (With my example, when Hello is printed to the console)
In the waterfall, Click on the mark that appears after 5000ms (with my example) and useful informations are displayed in the right pane.
While I'm not sure what your final goal is, you can wrap the function you're calling with the following wrapper function, which prints to the log whenever a function is being enqueued:
function wrapper(func) {
console.log(`'${func.name}' was enqueued`);
return func;
}
function foo() {
console.log('Hello')
}
setTimeout(wrapper(foo), 5000);
You can use a similar mechanism to maintain an array that'll contain all the functions that are currently waiting.

Is node.js setTimeout() working?

I'm new to Node.js. Is there something I need to do to get setTimeout() to work?
Here's a code snippet.
async code that sets appMsg.doneLoadTables = true when done
do {
console.log('waiting ... ' + appMsg.doneLoadTables);
setTimeout(function() { console.log('waiting ...'); }, 1000);
} while (!appMsg.doneLoadTables);
Symptoms:
(While the two calls to console.log are similar, only the first prints the value of appMsg.doneLoadTables.) Every result includes that value.
The spacing between calls to console.log is much closer than 1000 msec. (I suspect the spacing is as fast as the computer can process the loop shown here.)
While I would hope the async routines could continue to process during the delays I intended here, I've never seen this loop finish; it's as if the loop takes all processing resources and prevents the async routines from finishing their work and from setting the variable that'll end this loop.
I had this experience with Node 4.2.1; I continue to have this experience after installing Node 5.0.0.
I've seen that similar questions about setTimeout() have been asked here many times before. I hope my use of a IIFE inside setTimeout() makes this question distinct from all of those.
Thanks in advance for any help offered ...
JavaScript is single-threaded. setTimeout is not a form of sleep which pauses code at that line. It works by "scheduling" your callback for later, and execute it when the stack exhausts (the engine doing nothing) and is at least n milliseconds later, where n is the delay you placed in milliseconds.
Now your code doesn't work because it never exits the loop. The code doesn't get the chance to execute other code (the code you hope to run and change appMsg.doneLoadTables's value). All it does keep logging "waiting... [something]".
Essentially you are polling. What you could use instead is setInterval. When appMsg.doneLoadTables is true, you stop the polling by using clearInterval.
I am not 100% sure what is your goal ... however maybe this snippet takes you where you want to go (I opted for setTimeout instead of setInterval):
var appMsg = {doneLoadTables: false};
var stillLoading = function() {
if(false === appMsg.doneLoadTables) {
console.log('waiting ... ' + appMsg.doneLoadTables);
setTimeout(stillLoading, 50);
}
else {
console.log('Loading complete.');
process.exit();
}
}
stillLoading();
setTimeout(function(){
console.log('Setting appMsg.doneLoadTables = true');
appMsg.doneLoadTables = true;
}, 1000);
The script polls status every 50ms and marks "done" exactly after 1 second.
The output looks like this
waiting ... false
waiting ... false
waiting ... false
waiting ... false
...
Setting appMsg.doneLoadTables = true
Loading complete.
(While the two calls to console.log are similar, only the first prints the value of appMsg.doneLoadTables.) Every result includes that value.
That is the correct behavior since you never exit the while loop. You stay in the same event frame that keeps looping forever.
The spacing between calls to console.log is much closer than 1000 msec. (I suspect the spacing is as fast as the computer can process the loop shown here.)
That is the correct behavior again because you callbacks that you passed to setTimeout will never execute unless you exit the do-while loop, which you never do. So you just keep calling first console.log statement then you add a callback to event loop to execute in 1000 ms without ever giving it (the callback that you pass) the chance to execute.
While I would hope the async routines could continue to process during the delays I intended here, I've never seen this loop finish; it's as if the loop takes all processing resources and prevents the async routines from finishing their work and from setting the variable that'll end this loop.
The loop never finish because it doesn't have logic implemented that finishes it. "Async routines" can't continue because that would require exiting the current event frame (that runs infinite loop) and starting the next one that has you callback that you passed to setTimeout.
Hope my explanations will help you to understand how asynchronous JavaScript works.

How to make infinite calls for a div reload through Ajax synchronously

I'm kind of new to javascript and seriously, this async thing is driving me crazy.
I'm working on a project for displaying a div (which occupies all the screen) that reloads everytime with a different content and stays on screen for an X amount of time.
For example, I already created some static screens objects inside an array like this:
screenArray[0] = {ID:"987234", Name:"SampleScreen", Time:6000};
screenArray[1] = {ID:"837625", Name:"SampleScreen2", Time:10000};
So this is pretty much what I wanted to do if javascript worked synchronously:
function ScreenEngine(){
reloadScreenContent();// "loads" the first screen (this is just an Ajax div reload function)
for (var i = 0; i == screenArray.length+1; i++){
if (i == screenArray.length){ //when it gets to the latest screen, it goes to the first one
i = 0;
}
setTimeout(reloadScreenContent, screenArray[i].Time); // loads the second screen with the timeout of the first one (i=0)
}
}
(I'm just working on the timey wimey thingy, I'll deal with the content later.)
Saw some other posts about callback functions so javascript would work "synchronously" for the things I want and I even tried some of it and failed miserably doing it.
Even not understanding with details how I would make a callback function, I understand that (at least the way I "tried") it would stack forever because I'm asking javascript to do an infinite job.
I need a brainstorm how to solve this problem, maybe some tips using callback or a similar sample code so I can guide myself.
I think what you need to do is call the reload function inside the callback function itself.
If you're using jQuery for the ajax function, the code could look something like this:
function loadContent(){
$.getJSON("yourURL", callback)
}
function callback(data){
/*do something with the data*/
/*call loadContent at an interval */
window.setTimeout(loadContent, 2000 );
}
loadContent();
This was loadContent will get called 2s after the content has been loaded. Here's an example of a recursive ajax call, you can see in the console it's making the ajax call every 10s http://jsfiddle.net/w66peL7b/1/

Javascript: how to make changes to the document before function finishes running?

I want to create a function that when called would display a "Loading..." message, and display the results as soon as it finishes. when I do it like this:
function load() {
$('#status').html("loading...");
/* do something */
...
$('#status').html("done");
$('results').html(result);
}
The "loading" message never appears, after a while what a user sees is just the "done" message and the results. How can I make the "loading" text appear just the moment I want it to?
If "do something" is synchronous, the browser never gets a chance to update the UI between the two content changes.
To have the changes appear you need to do something like:
$('#status').html('loading...');
setTimeout(function() {
// do something
$('#status').html('done');
}, 0);
The setTimeout call gives the UI a chance to update the display before jumping into your "something".
Note that if possible you should try to ensure that "something" doesn't tie up your browser for a long time. Try to break the task up into multiple chunks, where each chunk is also dispatched using setTimeout().
Hard to tell without seeing the "stuff" part, but I hope this helps a little;
function load() {
$('#status').html("loading...");
function onLoaded(result) {
$('#status').html("done");
$('results').html(result);
}
// do your stuff here
// Not being able to see the "stuff", I guess you do some AJAX or something
// else which is asynchronous? if you do, at the end of your callback, add
// onLoaded(result)
}
The key is in the "do something". It depends on what you want to do but I would expect that you want to use jQuery's load() function.
Many jQuery functions accept 'callback functions' which are executed after the task is complete. The callback function section of the load() documentation should explain everything.

Run js function once when fired more than once

I have a Div that uses jQuery to load a file/contents with a javascript function..
function DoWork() {
// Do Stuff
}
Let's say the user can reload the Div and pull the same file/contents with the same js function DoWork(). The problem is, when the file is reloaded, the previous loaded function DoWork() is still running. How can I kill the previous fired DoWork() and restart it?
Javascript is single-threaded, which means only one thing can be executing at a given moment. If DoWork is already "running" it's either a) blocking all other JS code, and you have no choice but to let it finish since you have no way to execute any interruption code until it finishes on its own, or b) DoWork is scheduled to fire off on an interval via setTimeout() or setInterval().
If it's the latter case, setTimeout() and setInterval() return an ID. Store that ID somewhere and call clearTimeout(doWork_timeout_id) or clearInterval(doWork_interval_id) according to how you started it.
You can build a simple function that use: setTimeout and then each call to DoWork will call first to: clearTimeout. I don't really like this solution because you will waste CPU on setTimeout.
So another option will be to use web worker in DoWork (It will do lots of other good things for you in case you are working with big data as it's running in another thread) - then you get an option to send 'stop' message each time you start the work of DoWork().
Are you using ajax to load the div's contents? if so, the better way is as follows:
var doWorkAjax=null;
function DoWork(){
if (doWorkAjax) doWorkAjax.abort();
doWorkAjax = $.ajax(url, data, function(result){
....
doWorkAjax=null;
});
}

Categories