问题:一个函数可以忽略一个回调,阻止它再次触发,而它当前正在执行一个先前执行过的任务吗?
我有两个功能。函数#1使用带有回调函数的setTimeout
触发音频文件。它使用Math.round(Math.random() * aStartMax) + aStartMin;
以稍微随机的时间在一个循环中发出声音。功能#2执行可视动画,需要一定的时间才能完成。目前,每当声音由功能#1触发时,回调执行执行视觉动画的功能#2。问题在于,#1函数以比函数#2动画完成所用频率更高的频率发出声音,导致动画跳回到它的开始(它看起来很奇怪)。我不想减慢函数#1的触发频率,我只是希望函数#2忽略它已经运行时收到的回调。这可能吗?这样,声音可以以任何频率发射,但视觉动画只有在当前不运动时才会执行。
// FUNCTION #1: Audio function
(function loop() {
var rand = Math.round(Math.random() * aStartMax) + aStartMin;
setTimeout(function() {
playDuration = Math.floor((Math.random() * aPlayDurationMax) + aPlayDurationMin);
setTimeout(function () {
var sound = new Howl({
src: [soundFileName],
autoplay: true,
loop: true,
volume: (Math.random() * 0.8) + aVolumeMin,
fade: 0
});
var id2 = sound.play();
sound.fade(0, 1, aFadeIn, id2)
{
do_the_thing($('.a')); // << callback for function #2
};
setTimeout(function () {
sound.fade(1, 0, aFadeOut, id2);
}, playDuration);
}, aWaitToPlay);
loop(); // calls the audio function to execute again
}, rand);
}());
// FUNCTION #2: Visual function
function do_the_thing($elements) {
var delay = $elements.children().length * universalBoxTime;
setTimeout(function() {
$elements.makisu('toggle');
$elements.makisu({
selector: 'dd',
overlap: .7,
speed: 2
});
}, 0);
}
我已经读过,我可以使用setTimeout
设置我的#2函数,如下所示。但是我认为这不会允许函数忽略/删除新的回调,而是会简单地提示它们以便以后触发它们?
function yourfoo() {
// code
setTimeout(yourfoo, 3000);
}
setTimeout(yourfoo, 3000);
如果变量正在运行,则将回调函数2的状态保存在变量中。如果是,请不要执行它。如果不是,请执行它。检查下面的伪代码
var isRunning = false;
if(!isRunning) {
// callback function 2
}
function callback2() {
// execute it
isRunning = false;
}
您可以通过将该信息存储在自身来存储函数(或它的回调)是否仍在运行。我不确定函数#2何时完成(可能在delay
过后?),但这是一个例子:
function do_the_thing() {
if ( do_the_thing.running ) return;
do_the_thing.running = true;
// your code
setTimeout( () => do_the_thing.running = false, 1000 );
}
这将使do_the_thing
中的实际函数体执行每秒最多一次。理想情况下,当do_the_thing.running = false
实际执行时,你会设置do_the_thing
。