simultaneous functions javascript - javascript

I got this code, it's supposed to toggle elements, following a repetitive patron, that will grow up randomly, my start function executes my runp() function at simultaneous, and it got all messy. i would need to wait until runp() finishes to continue executing. Thanks
function runp(patron){
var x = 0;
var intervalID = setInterval(function () {
$("#container"+patron[x]).toggle(1).delay(1000).toggle(1).delay(1000);
if (++x === 20) {
window.clearInterval(intervalID);
}
}, 2000);
}
function start(patron, patronl){
while (patron.length<20){
patron.push(rand(1,4));
runp(patron);
}
}

You can use .queue()
// alternatively pass randomly shuffled array of elements to `$.map()`
$({}).queue("toggle", $.map($("[id^=container]"), function(el) {
return function(next) {
return $(el).toggle(1).delay(1000).toggle(1).delay(1000)
.promise().then(next)
}
})).dequeue("toggle")

Related

Calling two javascript functions one from each other

I have two functions for eg., runslider() and runslider1().
runslider() runs after the document is loaded and I need to call runslider1() after finishing runslider(). Then again runslider() after runslider1(). This process should happen like infinite loop. Can someone help me please.
I have tried to keep them like callbacks. But that didn't work.
function runSlider(runslider1){
alert("run")
runSlider1(runSlider());
}
function runSlider1(runslider){
alert("run1");
runSlider(runSlider1());
}
if you want your functions to be called over and over again try using setInterval
function runSlider(){
alert("run");
runSlider1();
}
function runSlider1(){
alert("run1");
}
setInterval(runSlider, 100);
This will cause both functions to be called in that order repeatedly every 100ms. It seems like this is the behavior you are looking for.
The comments above are correct - you will cause a stack overflow.
Don't know why you would need this, but I cleaned your code for you:
function runSlider() {
alert('run');
runSlider1();
}
function runSlider1() {
alert('run1');
runSlider();
}
You can create infinite loop like this you just need to call one function.
var runSlider = function() {
console.log("run")
runSlider1()
}
var runSlider1 = function() {
console.log("run1");
setTimeout(function() {
runSlider()
}, 1000)
}
runSlider()
Another solution is:
function runSlider() {
console.log("run");
runSlider1();
setTimeout(runSlider1(), 1000) // Calls runSlider1() after 1 second(1000 millisecond). You can change it.
}
function runSlider1() {
console.log("run1");
setTimeout(runSlider(), 1000) // Calls runSlider1() after 1 second(1000 millisecond).
}
runSlider(); // Starts the cycle
var maxCalls = 0;
function run1(cb) {
alert('run1');
if (maxCalls++ < 5) { //Added this to avoid an infinite loop
cb(run1); //We want the function run after cb to be this one
}
}
function run2(cb) {
alert('run2');
if (maxCalls++ < 5) {
cb(run2);
}
}
This is the way to call one function from another. If you create an infinite loop, you will freeze the browser up. If you want the two functions running constantly, its best to release execution for a bit with a setInterval call instead.
var runFunc = 0;
var run1 = function() {
alert('run1');
};
var run2 = function() {
alert('run2');
};
var run = function() {
!(++runFunc) ? run2 : run1; //Alternate between calling each function
}
var stopRunning = function() { //Call this to stop the functions running
clearInterval(runInterval);
};
var runInterval = setInterval(run, 1000); //Calls the function every second

Applying delay between each iteration of jQuery's .each() method

Having some problems with the following block of code:
$('.merge').each(function(index) {
var mergeEl = $(this);
setTimeout(function() {
self.mergeOne(mergeEl, self, index - (length - 1));
}, 500);
});
I'm trying to apply a .500 second delay between each call of mergeOne, but this code only applies a .500 second delay before calling mergeOne on all the elements in the array simultaneously.
If someone could explain why this code doesn't work and possibly a working solution that would be awesome, thanks!
Here's a general function you can use to iterate through a jQuery object's collection, with a delay between each iteration:
function delayedEach($els, timeout, callback, continuous) {
var iterator;
iterator = function (index) {
var cur;
if (index >= $els.length) {
if (!continuous) {
return;
}
index = 0;
}
cur = $els[index];
callback.call(cur, index, cur);
setTimeout(function () {
iterator(++index);
}, timeout);
};
iterator(0);
}
DEMO: http://jsfiddle.net/7Ra9K/ (loop through once)
DEMO: http://jsfiddle.net/42tXp/ (continuous looping)
The context and arguments passed to your callback should be the same as how .each() does it.
If you want to make it a jQuery plugin, so it can be called like $("selector").delayedEach(5000, func..., then you could use this:
$.fn.delayedEach = function (timeout, callback, continuous) {
var $els, iterator;
$els = this;
iterator = function (index) {
var cur;
if (index >= $els.length) {
if (!continuous) {
return;
}
index = 0;
}
cur = $els[index];
callback.call(cur, index, cur);
setTimeout(function () {
iterator(++index);
}, timeout);
};
iterator(0);
};
DEMO: http://jsfiddle.net/VGH25/ (loop through once)
DEMO: http://jsfiddle.net/NYdp7/ (continuous looping)
UPDATE
I added the ability to continuously loop through the elements, as an extra parameter. Passing true will continuously loop, while passing false or nothing (or something falsey) will only loop over the elements once. The code and fiddles include the changes.

Javascript: Force new loop iteration in setInterval

I have a setInterval loop. It's set to 3500 milliseconds, like so:-
var loop = setInterval(function() { /*stuff*/ }, 3500);
At one point in 'stuff' if a certain situation occurs, I want to force a new iteration of the loop and NOT WAIT for the 3500 milliseconds. How is that possible? Is it continue or do I just need to frame the process differently?
You could try writing an anonymous self-calling function using setTimeout instead of setInterval:
var i = 0;
(function() {
// stuff
i++;
if (i % 2 == 0) {
// If some condition occurs inside the function, then call itself once again
// immediately
arguments.callee();
} else {
// otherwise call itself in 3 and a half seconds
window.setTimeout(arguments.callee, 3500);
}
})();​ // <-- call-itself immediately to start the iteration
UPDATE:
Due to a disagreement expressed in the comments section against the usage of arguments.callee, here's how the same could be achieved using a named function:
var i = 0;
var doStuff = function() {
// stuff
i++;
if (i % 2 == 0) {
// If some condition occurs inside the function, then call itself once again
// immediately
doStuff();
} else {
// otherwise call itself in 3 and a half seconds
window.setTimeout(doStuff, 3500);
}
};
doStuff();
You can use something like this... using setTimeout instead of setInterval...
<script type="text/javascript">
var show;
var done = false;
show = setTimeout(showHideForm, 3500);
function showHideForm() {
// Do something
if(done) {
clearTimeout(show);
show = setTimeout(showHideForm, 2000);
}
}
</script>
clearTimeout takes as argument the handle which is returned by setTimeout.
Use a named function and call it when you want.
var loop = setInterval(loopFunc, 3500);
function loopFunc(){
//do something
}
function anticipate(){
clearInterval(loop); //Stop interval
loopFunc(); //Call your function
loop = setInterval(loopFunc, 3500); //Reset the interval if you want
}
My contrived example:
var time = 3500,
loops = 0,
loop;
(function run(){
var wait = time,
dontwait = false;
if (loops++ == 5) {
loops = 0;
dontwait = 1000;
}
console.log('Interval: ', dontwait || wait);
return loop = setTimeout(run, dontwait || wait);
})();​
http://jsfiddle.net/NX43d/1/
Basically, a self-invoking function looping back on a self-calling function, with (!) shorthand variable switching. Nifty.
function looper(t) {
var loop = setInterval(function() {
document.write(s++);
if (mycondition) { // here is your condition
loopagain(200); // specify the time which new loop will do
loop = window.clearInterval(loop); // clear the first interval
return; // exit from this function!
}
}, t);
}
window.onload = looper(1000); // this will have default setInterval function time ans will start at window load!
function loopagain(t) {
looper(t);
}​
http://jsfiddle.net/tFCZP/

Greasemonkey delay... setTimeout doesnt work ok

I've been playing around with a site, in which I want to continue clicking a button for i amount of times every interval seconds.
My code is:
clickbidBtn1 = function() {
var bidBtn=document.getElementById("BidButton");
var interval = 15000;
for (var i=3; i>=0; i--){
setTimeout(bidBtn.click(1);,i*interval);
};
I've found out that GM executes all i amount of clicks at the same time, not with the intended delay. is there a way to delay the time of click? Say i wanted the function to click the button every 15 second for i amount of times.
I was thinking of giving it some more variables, and adding one variable in the settimeout code part, which only executes # the click, then comparing increased variables with current ones before going to the next settimeout... but haven't thought it through yet... it seems to be a complicated process for a simple process... :( i wll play around with it a bit
Use setInterval() for this.
One way:
var bidClickTimer = 0;
var numBidClicks = 0;
function clickbidBtn1 ()
{
var interval = 15000;
bidClickTimer = setInterval (function() {BidClick (); }, interval);
}
function BidClick ()
{
numBidClicks++;
if (numBidClicks > 3)
{
clearInterval (bidClickTimer);
bidClickTimer = "";
}
else
{
bidBtn.click (1);
}
}
clickbidBtn1 ();
Alternatively, without using global vars:
function clickbidBtn1 ()
{
var interval = 15000;
this.numBidClicks = 0;
this.bidClickTimer = 0;
this.BidClick = function () {
numBidClicks++;
if (numBidClicks > 3)
{
clearInterval (bidClickTimer);
bidClickTimer = "";
}
else
{
bidBtn.click (1);
}
};
this.bidClickTimer = setInterval (function(thisScope) {thisScope.BidClick (); }, interval, this);
}
clickbidBtn1 ();
Just to explain why your code does not work: You are calling the .click method immediately (putting () after a function name calls the function) and actually passing the return value of that function to setTimeout. The for loop is so fast that everything seem to happen at the same time.
You have to pass a function reference to setTimeout, e.g. an anonymous function:
setTimeout(function() {
bidBtn.click(1);
}, i*interval);

Best way to have event occur n times?

I use the following code to create countdowns in Javascript. n is the number of times to repeat, freq is the number of milliseconds to wait before executing, funN is a function to call on each iteration (typically a function that updates part of the DOM) and funDone is the function to call when the countdown is complete.
function timer(n, freq, funN, funDone)
{
if(n == 0){
funDone();
}else{
setTimeout(function(){funN(n-1); timer(n-1, freq, funN, funDone);}, freq);
}
}
It can be called like so:
timer(10,
1000, /* 1 second */
function(n){console.log("(A) Counting: "+n);},
function() {console.log("(A) Done!");}
);
timer(10,
500,
function(n){console.log("(B) Counting: "+n);},
function() {console.log("(B) Done!");}
);
The advantage of this is that I can call timer() as many times as I want without worrying about global variables etc. Is there a better way to do this? Is there a clean way to make setInterval stop after a certain number of calls (without using global variables)? This code also creates a new lambda function with each call to setTimeout which seems like it could be problematic for large countdowns (I'm not sure how javascript's garbage collector handles this).
Is there a better way to do this? Thanks.
This is basically the same idea as #balabaster, but it is tested, uses prototype, and has a little more flexible interface.
var CountDownTimer = function(callback,n,interval) {
this.initialize(callback,n,interval);
}
CountDownTimer.prototype = {
_times : 0,
_interval: 1000,
_callback: null,
constructor: CountDownTimer,
initialize: function(callback,n,interval) {
this._callback = callback;
this.setTimes(n);
this.setInterval(interval);
},
setTimes: function(n) {
if (n)
this._times = n
else
this._times = 0;
},
setInterval: function(interval) {
if (interval)
this._interval = interval
else
this._interval = 1000;
},
start: function() {
this._handleExpiration(this,this._times);
},
_handleExpiration: function(timer,counter) {
if (counter > 0) {
if (timer._callback) timer._callback(counter);
setTimeout( function() {
timer._handleExpiration(timer,counter-1);
},
timer._interval
);
}
}
};
var timer = new CountDownTimer(function(i) { alert(i); },10);
...
<input type='button' value='Start Timer' onclick='timer.start();' />
I'd create an object that receives a counter and receives a function pointer to execute, something akin to the following pseudo code:
TimedIteration = function(interval, iterations, methodToRun, completedMethod){
var counter = iterations;
var timerElapsed = methodToRun; //Link to timedMethod() method
var completed = callbackMethod;
onTimerElapsed = function(){
if (timerElapsed != null)
timerElapsed();
}
onComplete = function(){
if (completed != null)
completed();
}
timedMethod = function(){
if (counter != null)
if (counter > 0) {
setTimeOut(interval, onTimerElapsed);
counter--;
}
else
onComplete();
this = null;
}
}
if ((counter != null)&&(counter > 0)){
//Trip the initial iteration...
setTimeOut(interval, timedMethod);
counter--;
}
}
obviously this is pseudo code, I've not tested it in an IDE and syntactically I'm not sure if it'll work as is [I'd be astonished if it does], but basically what you're doing is you're creating a wrapper object that receives a time interval, a number of iterations and a method to run upon the timer elapsed.
You'd then call this on your method to run like so:
function myMethod(){
doSomething();
}
function doWhenComplete(){
doSomethingElse();
}
new TimedIteration(1000, 10, myMethod, doWhenComplete);
I like your original solution better than the proposed alternatives, so I just changed it to not create a new function for every iteration (and the argument of fun() is now the value before decrement - change if needed...)
function timer(n, delay, fun, callback) {
setTimeout(
function() {
fun(n);
if(n-- > 0) setTimeout(arguments.callee, delay);
else if(callback) callback();
},
delay);
}

Categories

Resources