功能仍在执行任务时停止回调

时间:2017-12-21 17:15:19

标签: javascript animation audio callback settimeout

问题:一个函数可以忽略一个回调,阻止它再次触发,而它当前正在执行之前执行过的任务吗?

我有两个功能。 功能#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 个答案:

答案 0 :(得分:1)

如果回调函数2正在运行,则将其保存在变量中。如果是,请不要执行它。如果不是,请执行它。检查下面的伪代码

var isRunning = false;

if(!isRunning) {
   // callback function 2
}

function callback2() {
// execute it
isRunning = false;
}

答案 1 :(得分:0)

您可以通过将该信息存储在自身来存储该函数(或它的回调)是否仍在运行。我不确定函数#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