How to execute something only once within if-loop?

15,111

Solution 1

Take a Boolean variable like

var checkOnce= false;
if (myVariable >= 10 && myVariable <= 30) {
checkOnce=true;
    sound.play("myFirstSound"); 
    } 
    else if (myVariable >= 31 && myVariable <= 60) {
checkOnce=true;
    sound.play("mySecondSound");
    } else { etc etc...

In loop check the value of checkOnce. Loop will run till checkOnce=false

Solution 2

Create a boolean flag and play the sound only when false.

var isPlayed = false;
var oldValue = myVariable;

if (myVariable >= 10 && myVariable <= 30 && !isPlayed) {
    sound.play("myFirstSound"); 
    isPlayed = false;
} 

Then initialize variable when needed... For what you say i guess you will need a variable to compare the values inside the loop and set isPlayed flag to false:

if (myVariable != oldValue)
    isPlayed = false;

Solution 3

Just use a boolean variable.

var alreadyPlayed = false;

for(somecondition){
   if(alreadyPlayed) continue;

   sound.play("myFirstSound");
   alreadyPlayed = true;
}

You get the idea.

Solution 4

The boolean value is a good idea. You could also make a use of the onend property of the sound object, so you will know when you can start playing the sound again. Like this:

var playing = false;
sound.onend = function () { playing = false;  };

while (condition) {
   if (!playing & ...)
       ...
   ...
}

Solution 5

Saw your edit to the question, add a delay to the next trigger, the compass might be firing too rapidly. Not familiar with compass.js but as I can see it, it fires per degree, and that is a lot... if you tilt the phone 180degrees thats 180 triggers. Something like,

setTimeout(function() { your_func(); }, 50); 

for a 50ms delay

You can also limit the triggers available from 360 to 36 or less by adding a counter of 10, 1 degree is for 1 count. So it triggers only after 10 degree movement.

$(function(){
var counter = 0;
Compass.watch(function (heading) {
   if(counter <=10){
     counter++;
    }
    else{ 
   counter = 0;
  $('.degrees').text(Math.floor(heading) + '°');
  $('#rotate').css('-webkit-transform', 'rotate(' + (-heading) + 'deg)');

   if (heading >= 10 && heading <= 30) {
   sound.play("myFirstSound"); 
   } 
   else if (heading >= 31 && heading <= 60) {
   sound.play("mySecondSound");
   } else { etc etc...
   }       
   });
});
Share:
15,111
ifthisthenthat
Author by

ifthisthenthat

Updated on June 04, 2022

Comments

  • ifthisthenthat
    ifthisthenthat almost 2 years

    EDIT (more specific):

    I have the following situation. I am building an experimental synthesizer interface with JavaScript. I am using the howler.js plugin to handle audio. The idea is that a sound is played if a certain condition is met. I have a number stored variable whose value changes via the heading of an iPhone compass. I use compass.js. It has a variable called heading.

    $(function(){
    
        Compass.watch(function (heading) {
          $('.degrees').text(Math.floor(heading) + '°');
          $('#rotate').css('-webkit-transform', 'rotate(' + (-heading) + 'deg)');
    
           if (heading >= 10 && heading <= 30) {
           sound.play("myFirstSound"); 
           } 
           else if (heading >= 31 && heading <= 60) {
           sound.play("mySecondSound");
           } else { etc etc...
           });
    });
    

    Even if heading is constant the .play command is executed not once but over and over again causing the audio engine to run out of memory. How can I execute the commands within the if loops only once? I can not access the value of heading outside the compass function. I always get var heading does not exist error.