codeyashu codeyashu - 13 days ago 9
CSS Question

Come out of a function after an event in JavaScript

I have written this function which simulates a traffic signal on a webpage using javascript. Using set interval it repeats every 20 seconds. Now i need to exit from the function when there is an event more specifically a message sent by server using socket.io . Now I know that I can just clear the interval so the function is not repeated again however it doesnot stop at that very instant, which is what I need. Is it possible to do this?



(function startlights(){

socket.on('emergency', function(msg){ // I need to exit //startLights function when 'emergency' event occurs
console.log("mayhem "+msg);
});


setTimeout(function(){
r1.css("background-color", "black");
g1.css("background-color","green");
r4.css("background-color", "red");
y4.css("background-color","black");
},1000);
setTimeout(function(){
g1.css("background-color","black");
y1.css("background-color","yellow");
},5000);
setTimeout(function(){
r1.css("background-color", "red");
y1.css("background-color","black");
r2.css("background-color", "black");
g2.css("background-color","green");
},6000);
setTimeout(function(){
y2.css("background-color","yellow");
g2.css("background-color","black");
},10000);
setTimeout(function(){
y2.css("background-color","black");
r2.css("background-color", "red");
g3.css("background-color","green");
r3.css("background-color", "black");
},11000);
setTimeout(function(){
y3.css("background-color","yellow");
g3.css("background-color", "black");

},15000);
setTimeout(function(){
y3.css("background-color","black");
r3.css("background-color", "red");
g4.css("background-color","green");
r4.css("background-color", "black");
},16000);
setTimeout(function(){
y4.css("background-color","yellow");
g4.css("background-color", "black");
},20000);

}());

var repeatLights = setInterval(startlights,20000);




Answer

Just store the results of setTimeout() and call clearTimeout() on them. For example:

function startlights() {
  socket.on('emergency', function(msg) {
    for (var i = 0; i < timeouts.length; ++i)
      clearTimeout(timeouts[i]);
    clearInterval(repeatLights);
    console.log('mayhem  ' + msg);
  });

  var timeouts = [
    setTimeout(function() {
      r1.css("background-color", "black");
      g1.css("background-color","green");
      r4.css("background-color", "red");
      y4.css("background-color","black");
    }, 1000),

    setTimeout(function() {
      g1.css("background-color","black");
      y1.css("background-color","yellow");
    }, 5000),

    setTimeout(function() {
      r1.css("background-color", "red");
      y1.css("background-color","black");
      r2.css("background-color", "black");
      g2.css("background-color","green");
    }, 6000),

    setTimeout(function() {
      y2.css("background-color","yellow");
      g2.css("background-color","black");
    }, 10000),

    setTimeout(function() {
      y2.css("background-color","black");
      r2.css("background-color", "red");
      g3.css("background-color","green");
      r3.css("background-color", "black");
    }, 11000),

    setTimeout(function() {
      y3.css("background-color","yellow");
      g3.css("background-color", "black");
    }, 15000),

    setTimeout(function() {
      y3.css("background-color","black");
      r3.css("background-color", "red");
      g4.css("background-color","green");
      r4.css("background-color", "black");
    }, 16000),

    setTimeout(function() {
      y4.css("background-color","yellow");
      g4.css("background-color", "black");
    }, 20000)
  ];
}

var repeatLights = setInterval(startlights, 20000);

I should also point out that you will want to either only add an 'emergency' event handler once or remove any existing 'emergency' event handlers at the start of startlights(), otherwise you will continually add a new 'emergency' event handler every time startlights() is called.