How to make a variable timer sequence which runs infinitive - javascript

I have n parameters which have to be run in sequence for t seconds each. All the data is stored in an array which is loaded dynamically through ajax and json and exists of: function parameters p and time to sleep t
function(p1), for 30 seconds; when it completes function(p2) for 15 seconds etc etc
Until the array is complete; then we have to start all over.
The number of parameters and its time being displayed are not determined on forehand.
How can I implement this with javascript?
//edit:
I tried to make one big function with function(p1) starting at t=0; function(p2) starting at t=t1; function(p3) starting at t=t1+t3
But it felt 'stupid' and overdone....

I suspect you array looks like
var myarray=[['p1',30],['p2',15] ...];
In this case you could
function runme(i) {
if (i>=myarray.length) i=0;
var p=myarray[i][0];
var t=myarray[i][1];
myfunction(p);
i=i+1;
window.setTimeout('runme('+i+');',1000*t);
}
Edit
And ofcourse
runme(0);
to start.

Related

Javascript Timeout between for loop?

So it's probably some mis-understanding on the best way to use the setTimeout method provided by javascript but im having trouble implementing it in a way that makes sense.
Essentially I have an Array with numbers between 1-4 and each number corresponds to a button getting let up.
for(let i = 0;i < arr.length;i++){
view.renderPane(arr[i]) //All this does is set the .css
view.renderPane is pretty simple:(I have a separate function that clears(sets opacity back to .5) it, but if possible i'd like to just put that in here.
renderPane(pane){
$("."+pane).css("opacity", "1");
console.log("Activating Pane "+ pane)
}
So I tried setting up a timeout thinking I could call the renderPane within the timeout, but all it did was set up a bunch of timeouts that basically fired off after X seconds (or milliseconds). Is there a way I can call the renderPane(pane) function every 1 second (to set up a delay) inside this for loop? or will I need to set up something else?
No need to use a loop, just create a function which continuously schedules itself with setTimeout until it's done — in this case, it removes an item from the array in each call and stops when the array is empty:
(function callee() {
view.renderPane(arr.shift());
if (arr.length)
setTimeout(callee, 1000);
})();
Example: https://jsfiddle.net/2fwht35d/
There are many other ways to implement this behaviour, but this should give you a good starting point.

Date in Javascript Div loop not updating correctly

I'm trying to generate 3 divs in a for loop and insert the datetime in each iteration . The problem I'm running into is while the function generates the three div's correctly it appends the same time to all 3 div's leaving me (JavaScript newbie) to believe the Date() function is only being executed once . If any we could explain to me what is going on I would greatly appreciate it. Ideally I would like to replace the Date function with graph's and have a graph load in each div.
function gengraphs () {
for (i=0; i < 3; ++i) {
var divTag = document.createElement("div");
divTag.style.width ="1000px";
divTag.style.height ="600px";
divTag.id = "graph"+i;
document.body.appendChild(divTag);
divTag.innerHTML = Date();
// divTag.appendChild(getGraph(divTag));
// divTag.innerHTML = getGraph(divTag);
}
}
The server is executing the script fast enough (in milliseconds) that the date() returned is not visibly different. Try something to delay or use the increment variable i
The loop is being executed so quickly that you won't see a difference in time. Try calling the contents of your loop with a significant delay (e.g. 1s) and put it into a function as shown here: JavaScript sleep/wait before continuing

Adding 1 every second to a certain variable

I just want to add 1 to a certain variable every second while the program is running.
So basically it kind of performs something like x++ every second.
I see many setIntervals but they use var which is not working.
I'm new to Java so please bear with me.
Try the sleep command in your loop before running the x++. The sleep command is in milliseconds so you'll have something like the following pseudo code:
LoopWithConditional{
sleep(60000);
}
First, you need a thread-safe way to increment the int. The best way is to use java.util.concurrent.atomic.AtomicInteger.
Then, you need some timed task to increment that AtomicInteger every second. For that, you can use Timer.schedule.
private final AtomicInteger myInt = new AtomicInteger(0); // start at 0
public void startIncrementing() {
TimerTask task = new TimerTask() {
#Override
public void run() {
myInt.incrementAndGet();
}
}
Timer timer = new Timer(true); // you probably want a daemon thread here
timer.schedule(task, 0, 1000); // start right away, repeat every 1000 ms
}
If you want to be able to stop the increments, you'll need to save the timer into an instance variable so that you can call timer.cancel() on it when you want to stop incrementing.
I'd encourage you to read up on the javadocs of the various classes/methods here, because there's lots of juicy stuff (such as what a daemon thread is, etc).
You may use the JavaScript date object as follows:
//At the beginning of your app
var d = new Date();
var startSeconds = d.getTime()/1000
//Whenever you need the incremental variable by one every second
x = (d.getTime()/1000) - startSeconds

Making a function that adds a number to a variable every second in Javascript

Hey so basically I want to create a function that at every 1 second adds 1 or a changeable number to another variable.
I have been searching the internet for this but haven't been able to find it. I am guessing that it should be fairly simple.
var counter =0;
var value = 1; //the number to add. You can change it by modifying the variable
setInterval(function() {
counter+= value;
},1000);
but, if you want to add 1 per second, a much more efficient way would be
//set the initial value
var start = Date.now();
//create a function you can call anytime to get the diff
function getCurrentDiff() {
return (Date.now() - start)/1000;
}
then you don't have to be constantly running the add function, which gets expensive over time.
setInterval or setTimeout?
setTimeout(function(){number++;},1000);
or
setInterval(function(){number++;},1000);

Function to slow down a loop using callbacks gets messed up when used recursively

note: I may be using the word recursively wrong
I'm trying to create a script that runs through a long string of text, searching for the recurrence of substrings. For this I essentially do a for-loop from 12 to 3 (lengths of strings I want to check for recurrence), and for each of those lengths I use another for loop to define if the string of that length is present multiple times. A dumbed down example (untested, just for demonstration):
for(var len=12; len>3; len--) {
var recurring = [];
for(var pos = 0; pos < (inputString.length - len); pos++) {
var mystring = inputString.substr(pos, len);
// do a regex to check if mystring occurs more than once
// if so, push it into recurring and remove from inputString to prevent partial duplicates when mystring gets shorter
}
// output recurring strings
}
This all works, but obviously when I run this on a very long inputString it gets very slow. In fact, it freezes the browser, and any progress output that I want to show while the script runs is paused and shows up all at once when the script is done.
To prevent this, I created a function that is supposed to run through the for-loop in small batches at a time, using a callback function to proceed to the next batch. By using a basic version of this, I was able to output progress onto the page during what used to be a for-loop, even if it's going through thousands of loops:
var fragmentedFor = function($aFragmentLength, $aTotal, $aFunction, $aCallback)
{
var $lStart = 0,
$lFragmentLength = $aFragmentLength,
$lTotal = $aTotal,
$lFunction = $aFunction,
$lCallback = $aCallback;
// simulate a for loop, but in fragments to prevent the browser from freezing
(function forLoop ($aStart)
{
// run x loops at a time
var $lEnd = $lStart + $lFragmentLength;
// can't run the loop past the total length
if($lEnd > $lTotal )
$lEnd = $lTotal;
// the fragmented for loop
for(var $i = $lStart; $i < $lEnd; $i++) {
// run the function here
$lFunction({count: $i});
}
// next time, start from where we just left
$lStart += $lFragmentLength;
// is there room for more loops?
if($lStart < $aTotal) {
setTimeout(forLoop, 10);
} else {
// if not, run the callback
$lCallback();
}
})();
}
When I run this just once it seems to do what I want:
function myLoop(x) {
new fragmentedFor(
10, // amount of loops per run
x, // total amount of loops
function($aData) { console.log($aData.count); },
function() { console.log('finished') }
);
}
myLoop(1000);
However, when I want to call this one nested within another instance of such a loop, I run into trouble:
new fragmentedFor(
1,
5,
function($aData) { myLoop($aData.count * 100) },
function() { console.log('finished all') }
)
(I have copied my current files here: http://files.litso.com/vigenere/so/, which includes the fragmentedFor function so you can essentially paste these two functions in the console and see the result. This was a lot easier than putting it on jsfiddle and making that work, if you guys don't mind)
What appears to be happening is that the first run of myLoop is started, but since it's trying to run 0 * 100 times it ends safely, going to the second run. The second run of myLoop should go up to 100, but it runs to 19 before suddenly run 3 of myLoop kicks in.
From there on, the output seems to be totally mixed up, I figure because my callbacks are implemented incorrectly and the loops are not really waiting for eachother to finish.
What am I doing wrong here? How can I even start debugging where the problem lies, and how can I make sure that the independent runs of the for loop actually wait for eachother to finish?
-edit-
Here's a jsfiddle of an older working copy: http://jsfiddle.net/u2aKX/
This did not incorporate the fragmentedFor loop, it does have some callback functions which seemed to improve the performance compared to regular nested for-loops by 100%.
I figure because my callbacks are implemented incorrectly and the loops are not really waiting for eachother to finish.
What am I doing wrong here?
Your fragmentedFor expects the $aFunction to be synchronous, and as soon as it returns it schedules the next loop turn.
Yet, by using a nested fragmentedFor in that function, you're making it asynchronous - and the iterations of the inner loops will start to crossfire.
As you recogniced, you will have to let them wait to finish - which means hooking the next iteration on the callback of the previous one. You will have to write another fragmentedFor that deals with asynchronous iteration steps:
function fragmentedForAsync(from, to, body, callback) {
var i = from;
(function loop() {
if (i < to)
body(i++, loop); // pass itself as callback
else
callback();
})();
}
and then use it like this:
fragmentedForAsync(1, 5, function(i, callback) {
fragmentedFor(10, i*100, function(j) {
console.log(j);
}, function() {
console.log('finished '+1);
callback(); // next turn of outer loop
});
}, function() {
console.log('finished all')
});

Categories