简体   繁体   English

如果多次调用同一函数,该如何停止以前的实例?

[英]How to stop the previous instances of the same function if it's called multiple times?

I have written a custom animation function. 我已经编写了一个自定义动画功能。 It usually works just fine, but when I call animate(); 它通常可以正常工作,但是当我调用animate(); in rapid succession with different endCallbacks, sometimes the callbacks overlap really badly, causing the wrong action at the wrong time. 在使用不同的endCallbacks快速连续进行时,有时回调确实重叠得很严重,从而在错误的时间导致错误的操作。

The problem is that the function instantiates multiple times and executes untill the endValue is reached. 问题在于该函数实例化多次并执行直到达到endValue为止。 The currentValue is changed so fast that I get to see just the last value in my html page animation. currentValue变化太快了,以至于我只能看到html页面动画中的最后一个值。 This hiddes this unwanted behavior. 这掩盖了这种不必要的行为。

What I need when I call animate(); 调用animate();时需要什么animate(); a second time is to end the first instance of animate(); 第二次是结束animate();的第一个实例animate(); and trigger a new one with new values and a new callback. 并触发具有新值和新回调的新代码。 Also at the same time I want to stop the setTimeout() function just to make sure no wrong callback is triggered. 同时,我想停止setTimeout()函数只是为了确保没有触发错误的回调。

window.onload = function(){
    document.addEventListener('click', // some button
        function (){
            animate(1, 10);
        }, false
    );
}

function animate(startValue, endValue, callback, endCallback) {
    var startValue = startValue,
        currentValue = startValue,
        endValue = endValue,
        callback = callback,
        timeout = null;

    loopAnimation();
    function loopAnimation(){
        if (currentValue != endValue){
            timeout = setTimeout(function(){
                currentValue++;

                // Callback executes some page manipulation code
                if (typeof callback !== "undefined") callback(currentValue); 
                console.log(currentValue);
                loopAnimation();
            },500)
        } else {
            console.log("This callback triggers some specific changes in my page");
            if (typeof endCallback !== "undefined") endCallback();
        }
    }
}

Instead of seeing in the console: 1,2,3, - 1,4,2,5 ... 6,9,7,10,8,9,10 而不是在控制台中看到:1,2,3,-1,4,2,5 ... 6,9,7,10,8,9,10

I'd like to see just: 1,2,3, - 1,2 ... 7,8,9,10 我只想看:1,2,3,-1,2 ... 7,8,9,10

However, keep in mind that because of the way I use animate() in my script I can't relly on knowing the name or scope of the input variables. 但是,请记住,由于我在脚本中使用animate() ,我不能依赖于知道输入变量的名称或范围。 This cuts me from being able to solve it myself. 这使我无法自己解决问题。

While it isn't quite the implementation you're asking for, I wonder if Underscore's throttle or debounce would meet the need? 虽然这不是您所要求的实现,但我想知道Underscore的加速或反跳功能是否可以满足需要?

debounce will make sure your function is called no more than X times per second -- it'll still be executed once per every time called, but the subsequent calls will be delayed to meet your rate limit. 防反跳功能可以确保您的函数每秒被调用的次数不超过X次-每次调用仍将执行一次,但是后续的调用将被延迟以满足您的速率限制。 So if you called animate twice in quick succession, debounce can delay the second execution until 100ms after the first or what have you. 因此,如果您快速连续调用了两次动画,则防抖动可以将第二次执行延迟到第一次执行之后或100ms之后。

throttle will basically ignore calls that occur during the rate limit. 节流阀将基本上忽略速率限制期间发生的呼叫。 So if you call your animate 10 times within 100ms, you could have it throw out all but the first. 因此,如果您在100毫秒内对动画设置了10次调用,则除了第一个动画外,其他所有动画都将被丢弃。 (Actually, it'll do the first one, plus one at at the end of the wait period). (实际上,它将执行第一个操作,在等待期结束时执行一个操作)。

You don't need to use all of underscore to get these methods; 您无需使用所有下划线即可获得这些方法。 I've seen people frequently copy and pasting just the debounce and/or throttle functions from underscore. 我见过人们经常从下划线复制和粘贴反跳和/或油门功能。 If you google, you can find some standalone throttle or debounce implementations. 如果您使用的是Google,则可以找到一些独立的调节或反跳实现。

Throttle and debounce are commonly used in just your case, animation. 油门和反跳通常只用于您的情况动画。

For your original spec, to actually "end the first instance of animate()" -- there's no great reliable way to do that in javascript. 对于您的原始规范,实际上是“结束animate()的第一个实例” —在javascript中没有很好的可靠方法。 There's no real general purpose way to 'cancel' a function already being executed. 没有真正的通用方法来“取消”已经执行的功能。 If you can make it work with debounce or throttle, I think it will lead to less frustration. 如果您可以使其在防抖或节流的情况下工作,那么我认为它将减少沮丧感。

What you need is to store the last timeout id you used. 您需要存储上次使用的超时ID。 So next time you start a new animation, you clear any ongoing animation using this timeout id and clearTimeout . 因此,下次启动新动画时,请使用此超时id和clearTimeout清除所有正在进行的动画。
I found convenient to store the interval on the function itself. 我发现将间隔存储在函数本身上很方便。

See the jsbin here : http://jsbin.com/nadawezete/1/edit?js,console,output 在这里查看jsbin: http ://jsbin.com/nadawezete/1/edit?js,控制台,输出

window.onload = function(){
    document.addEventListener('click', // some button
        function (){
            animate(1, 10);
        }, false
    );
};

function animate(startValue, endValue, callback, endCallback) {   
    var currentValue = startValue;
    if (animate.timeout) clearTimeout(animate.timeout);
    loopAnimation();
    function loopAnimation(){
        if (currentValue != endValue){
            animate.timeout = setTimeout(function(){
                console.log(currentValue);
                currentValue++;    
                // Callback executes some page manipulation code
                if (callback ) callback(currentValue); 
                loopAnimation();
            },500);
        } else {
            console.log("This callback triggers some specific changes in my page");
            if (endCallback) endCallback();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何停止多次调用 function - How to stop function being called multiple times 停止多次编写相同的函数 - Stop writing the same function multiple times 多次调用同一JavaScript函数将停止先前的同一函数 - Calling the same JavaScript function multiple times stops the previous same function 滚动时停止多次调用 Function - Stop Function being called multiple times when scrolling 如何在前一次调用中执行相同的功能后多次调用一次函数? (JavaScript的) - How to call a function multiple times 1 second after the same function has been executed in a previous call? (javascript) 如何多次运行同一个 JS 函数并等待前一个完成? - How to run the same JS function multiple times and wait until the previous has finished? 如果多次调用一个选择器,是否在该函数中缓存的性能更高? - Is it more performant to cache a selector in a function if that function's called multiple times? JS中的多个字符替换-如何在同一函数中停止替换以前的结果 - Multiple character replacements in JS - how to stop replacements on previous results within the same function 防止多次调用相同的 javascript function - Prevent same javascript function being called multiple times axios 拦截器的错误 function 被多次调用 - axios interceptor's error function is called multiple times
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM