Claudio
Claudio

Reputation: 2037

Javascript - making 2 setInterval() be synchronous

I have 2 functions calling setInterval but I need them to be synchronous. Here is my code(yes, they are really simple).

var number1 = 0;

function caller(){
  go();
  come();
}

function go() {
  anim1 = setInterval("doActionGo()", 20);
}

function come() {
  anim2 = setInterval("doActionCome()", 20);
}

function doActionGo(){
  if(number1 < 1023) {
    number1++;
  } else {
    clearInterval(anim1);
  }
}

function doActionCome() {
  if (number1 > 0) {
    number1 = number1 - 1
  } else {
   clearInterval(anim2); 
}

functions doActionGo() and doActionCome() would be any code. Does anybody know how to solve it?

Regards!

Upvotes: 2

Views: 10048

Answers (4)

6502
6502

Reputation: 114461

To execute two animations in sequence just start the second one at the end of the first... for example:

var anim1, anim2;
var number = 0;

function animation1()
{
    number = number + 1;
    if (number > 1000)
    {
        clearInterval(anim1);
        anim2 = setInterval(animation2, 20);
    }
}

function animation2()
{
    number = number - 1;
    if (number < 0)
    {
        clearInterval(anim2);
    }
}

function start()
{
    anim1 = setInterval(animation1, 20);
}

Upvotes: 5

sitifensys
sitifensys

Reputation: 2034

As people already commented, JavaScript is single threaded. So running two functions simultaneously is impossible. However a couple of strategies can be used to simulate this.

  1. For GUI effects, interpolation can be used. Basically, a single function is responsible of transitioning things step by step by interpolating the start and end value(be it an opacity, a position, a variable, a state or whatever can be interpolated). A javascript library can use this simple concept to create effects for example.

  2. A second approach is to use co-routines available in javascript since version 1.7. This article (although a little old) describes how to simulate threading in javascript and can be a good starting point to understand the mechanism involved in a co-routine powered design.

Hope this will help :)

Upvotes: 0

Mic
Mic

Reputation: 25154

Here is way to call them in sequence:

var number1 = 0;

function caller(){
  go( come );
}

function go(comeFn) {
    var anim = setInterval(function(){
        if(number1 < 100) {
            number1++;
        } else {
            clearInterval(anim);
            comeFn();
        }
    }, 20);
}

function come() {
    var anim = setInterval(function(){
        if (number1 > 0) {
            number1--;
        } else {
            clearInterval(anim); 
        }
    }, 20);
}

And two comments:

  • you shouldn't use strings in setInterval('functionName', 30) but directly functions
  • if you don't use anim1 instead of var anim1 it is considered as a global variables

Upvotes: 2

mVChr
mVChr

Reputation: 50177

See demo of the following →

It wasn't really clear what you were asking, but it inspired me to write this mini animation queue. Maybe you or someone else will benefit from it:

var number1 = 0,
    number2 = 1023,
    queue = [];

// execute every XX miliseconds
function tick(delay) {

    // iterate through queue
    for (var i = 0, il = queue.length; i < il; i++) {

        if (queue[i]) {

            // execute each tick function
            queue[i].tick();

        }

    }

    // recall tick
    setTimeout(function() {
        tick(delay);
    }, delay);
}

// kill tick function of matching name
function qKill(name) {
    for (var i = 0, il = queue.length; i < il; i++) {
        if (queue[i]) {
            if (queue[i].name === name) {
                queue.splice(i, 1);
            }
        }
    }
}

var go = {
    name: 'go',
    tick: function() {
        if (number1 < number2) {
            number1++;
            // do whatever here
        } else {
            qKill('go');
        }
    }
};

var come = {
    name: 'come',
    tick: function() {
        if (number2 > number1) {
            number2 = number2 - 1;
            // do whatever here
        } else {
            qKill('come');
        }
    }
};

queue.push(go);
queue.push(come);

tick(20);

Demo →

Upvotes: 0

Related Questions