javascript 如何在if循环中只执行一次?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28813349/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 09:36:47  来源:igfitidea点击:

How to execute something only once within if-loop?

javascriptjqueryhtmlif-statementweb

提问by ifthisthenthat

EDIT (more specific):

编辑(更具体):

I have the following situation. I am building an experimental synthesizer interface with JavaScript. I am using the howler.jsplugin 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.

我有以下情况。我正在用 JavaScript 构建一个实验性的合成器界面。我正在使用howler.js插件来处理音频。这个想法是如果满足某个条件就会播放声音。我有一个数字存储变量,其值通过iPhone 指南针标题发生变化。 我使用compass.js。它有一个名为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 existerror.

即使标题不变,.play 命令也不是一次执行而是一遍又一遍地执行,导致音频引擎内存不足。如何只执行一次 if 循环中的命令?我无法访问指南针功能之外的航向值。我总是得到var 标题不存在错误。

回答by Jeremy Thille

Just use a boolean variable.

只需使用布尔变量。

var alreadyPlayed = false;

for(somecondition){
   if(alreadyPlayed) continue;

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

You get the idea.

你明白了。

回答by VSharma

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

在循环中检查 checkOnce 的值。循环将运行直到 checkOnce=false

回答by curlybracket

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

布尔值是个好主意。您还可以利用对象的onend属性sound,这样您就会知道何时可以再次开始播放声音。像这样:

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

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

回答by JaredT

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,

看到您对问题的编辑,为下一个触发器添加延迟,指南针可能触发得太快了。对 compass.js 不熟悉,但正如我所见,它每度触发一次,这很多……如果您将手机倾斜 180 度,则触发 180 度。就像是,

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

for a 50ms delay

延迟 50 毫秒

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.

您还可以通过添加 10 的计数器将可用的触发器限制在 360 到 36 或更少,1 度是 1 计数。所以它只有在移动 10 度后才会触发。

$(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...
   }       
   });
});

回答by Jordi Castilla

Create a boolean flagand play the sound only when false.

boolean flag仅在 时创建并播放声音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 isPlayedflag to false:

然后在需要时初始化变量......对于你所说的,我猜你需要一个变量来比较循环内的值并将isPlayed标志设置为false

if (myVariable != oldValue)
    isPlayed = false;

回答by GameAlchemist

Add just a small layer of abstraction that will keep track of what's currently playing.

添加一个小的抽象层来跟踪当前正在播放的内容。

var nameOfSoundPlaying = null;

function play(soundName) {
   if (nameOfSoundPlaying == soundName) { 
      return; 
   } else {
     if (nameOfSoundPlaying != null) {
        // stop currently playing sound (if still playing)
        ...
     }  
     nameOfSoundPlaying = soundName;
     sound.play(soundName);
   }
}

Then it'll simplify your code :

然后它会简化你的代码:

$(function(){

    Compass.watch(function (heading) {
      $('.degrees').text(Math.floor(heading) + '°');
      $('#rotate').css('-webkit-transform', 'rotate(' + (-heading) + 'deg)');

       if (heading >= 10 && heading <= 30) {
           play("myFirstSound"); 
       } 
       else if (heading >= 31 && heading <= 60) {
           play("mySecondSound");
       } else { etc etc...
       });
});