java script for grease monkey loop - javascript

what i need is a for or while loop that will re run the code every second
ive tried sleep() but i dont think it is working or i have got it right

Do not try to use a for or while loop for such timed operations. You'll have a hard time with reliable or accurate timing and usually end up railing the CPU, making the computer sluggish.
JavaScript provides the setInterval() function for these kinds of tasks. Also note that Greasemonkey has some caveats about how to use setInterval() and setTimeout().
So the code you want is like:
var timerVar = setInterval (function() {DoMeEverySecond (); }, 1000);
function DoMeEverySecond ()
{
//--- Your code here.
}
//--- When ready to stop the timer, run this code:
clearInterval (timerVar);
timerVar = "";

try
// where yourfunction is a method that contains your loop logic
setTimeout(yourfunction, 1000);
This will invoke the function every 1000 milliseconds without having to embed it into a while or for loop.
put it into your body onload or similar event

Related

How would you terminate an infinite loop (`setInterval`) in the console?

For instance, we could run
setInterval(function(){console.log("Hello, SO!")}, 2000);
Hello, SO! gets repeated every two seconds in the terminal. There are 6 repeats in the picture below.
Is there a key combination you could press or command you could type to stop the infinite loop in the console?
This is your best bet that I know of.
var interval = setInterval(() => console.log("hello, world"), 2000);
clearInterval(interval);
To kill intervals, you need a handle to them to pass to clearInterval(). In your image, after you execute setInterval(), you can see the handle is returned to the console as 4491. In this way, you can kill it like so:
clearInterval(4491);
Alternatively (and better), you should assign that handle return to a variable so you can kill it programmatically:
let interval = setInterval(() => console.log('Hello, SO!'), 2000);
clearInterval(interval);
Edit:
You can also brute-force. The handle is an int64 number, so it could potentially be enormous, but for almost any app, it'll be small since the handles are incremented. Note that this method could break other packages that rely on intervals.
for (var i = 1; i < 9999; i++) clearInterval(i);
You can stop script execution on the current page using the pause button described here. This will pause all JS on the page though, not just your interval.

setTimeout blocking issue

I'm writing a "Game of Life" in javascript. I have all the logic done in a function called doGeneration(). I can repeatedly call this from the console and everything goes as planned, however, if I put it in a while loop the execution blocks the UI and I just see the end result (eventually).
while (existence) {
doGeneration();
}
If I add a setTimeout(), even with a generation limit of say 15, the browser actually crashes (Canary, Chrome).
while (existence) {
setTimeout(function() {
doGeneration();
},100);
}
How can I call doGeneration() once every second or so without blocking the DOM/UI?
You want setInterval
var intervalId = setInterval(function() {
doGeneration();
}, 1000);
// call this to stop it
clearInterval(intervalId);
I would use requestAnimationFrame(doGeneration). The idea of this function is to let the browser decide at what interval the game logic or animation is executed. This comes with potential benefits.
https://hacks.mozilla.org/2011/08/animating-with-javascript-from-setinterval-to-requestanimationframe/
Rather than using setINterval or setTimeout and assume some random time interval will be enough for the UI to update you shoul/could make the doGeneration smart enough to call itself after dom was updated and if the condition of existence is satisfied.

HTML/JavaScript: How to run a loop while running other code?

I want to have code that simply will count up by one every second or so. However, I also want to be able to run other code alongside it.
Example:
while(true){
Number + 1 + OtherNumber = Number
}
And also be able to run this at the same time:
function onButtonPress() {
OtherNumber++
}
Note: I do not want to increment otherNumber at an interval, but rather on the press of a button.
You can use setInterval:
var intervalId = setInterval(function() {
OtherNumber++;
}, 1000);
It will increase OtherNumber by one approximately every second.
setInterval returns ID of interval, which can be used to stop it:
clearInterval(intervalId);
Demo snippet:
document.body.innerHTML += "Start<br/>";
setInterval(function() {
document.body.innerHTML += "Interval step<br/>";
}, 1000);
document.body.innerHTML += "Look! Code is completed before interval step<br/>";
If you want to run code as two separate threads you will have to use web Workers as Javascript is single threaded and can not run more than one function at a time.
If you create a function
function workForever(){
while(true){
.. do work
}
}
You will completely block all code, no events will get called, no other javascript will be executed. Most browsers will throw up a dialog reporting that a function is taking a long time do you want to kill the page. But your code is stuck in that loop and can only be exited from within the loop itself.
WebWorkers are a good solution to multitasking in the Javascript environment, but you still need to provide some non execution time to allow the webworkers to communicate. The while(true) will block all communication with the workers, in effect making them useless.
SetInterval, setTimeout, requestAnimationFrame will also be blocked. Javascript unfortunately is single threaded and will never be able to run two functions at the same time.

Javascript setInterval runs only one time

setInterval(this.Animate(), this.speed);
This is expected to be run every this.speed times. Yes, but the browsers run it only one time. What are the possible reasons for that?
Try to run your function without the parentheses, when you put parentheses it always calls the function instead of passing it, which is what you want here:
setInterval(this.Animate, this.speed);
If it still doesn't work, you should debug and find out what is the scope for 'this', as 'this' might change. You can do that by adding a breakpoint in your browser's JS debugger.
Also, you can try this to avoid the scope problem with 'apply'
var animate = this.animate.apply(this)
setInterval(animate, this.speed);
p.s: It might be a good choice to avoid setInterval for animation as they might queue and then fire at once. Instead call setTimedout once and again at the end of the function (this.Animate) as so to create a loop.
If Animate is a derived function from the prototype, you'll have to use:
setInterval(this.Animate.bind(this), this.speed);
Do the following:
setInterval(this.Animate, this.speed);
You are executing the function instead of assigning a reference to the function to be executed at a certain interval...
Let us look at your code
setInterval(this.Animate(), this.speed);
What it is saying is run the function this.Animate() right away and store what ever it returns to be called.
What you want to do is create a closure
var that = this;
setInterval( function(){ that.Animate() }, this.speed);
The that maintains the current scope.
If you're looking for a JQuery refresh script, try:
refreshId = setInterval(function() {
// Events or Actions
}, 5000);
If you ever want to Pause or Stop this, use clear interval: clearInterval(refreshId);.

How can I run some code on all the nodes in a tree?

I want to run some code on all my treeView nodes depending on a value returned from the database and repeat this until a certain value is returned.
I was thinking that:
Give all my tree nodes the same css class so I can access them from JQuery
have a timer in my JQuery function that used ajax to go to the database, when a certain value is returned then stop the timer
Two questions here. How can I make my function run for each of the nodes and how do I do a timer in JavaScript, so:
$(function(){
$('cssClassOfAllMyNodes').WhatFunctionToCallHere?((){
//How do I do Timer functionality in JavaScript?
ForEachTimeInterval
{
//use Ajax to go to database and retrieve a value
AjaxCallBackFunction(result)
{
if (result = 1)
//How to stop the timer here?
}
}
});
});
Hope i'm clear. Thanks a lot
thanks a lot for the answer. And i would like you to comment on the design.
Bascially what i'm trying to acheive is a Windows Wokflow type functionality where each node in my tree updates its image depending on its status, where its status is got from querying the database with a key unique to the tree node. I'm open to ideas on other ways to implement this if you have any. thanks again
Without commenting on your design you can refer to these
$.each()
setTimeout() or setInterval()
You can do:
$(function(){
$('cssClassOfAllMyNodes').each(function (){
// Do something with "this" - "this" refers to current node.
});
});
Te proper way to handle timers in JS is to have a reference to each timeout or interval and then clearing them out.
The difference between them is:
The timeout will only run once, unless stopped before;
The interval will run indefinitely, until stopped.
So you can do something like:
var delay = 2000; // miliseconds
var timer = setTimeout("functionToBeCalled", delay);
clearTimeout(timer); // whenever you need.
Please note you can pass a string to setTimeout (same with setInterval) with the name of the function to be called. Or you could pass a reference to the function itself:
var callback = function () { alert(1); };
var timer = setTimeout(callback, delay);
Be sure not to set an Interval for AJAX requests, because you response might be delayed and successive calls to the server could eventually overlap.
Instead, you should call setTimeout and when the answer arrives then call setTimeout again.

Categories

Resources