Javascript 如何停止相同函数的前一个实例,如果它';他打了好几次电话?

Javascript 如何停止相同函数的前一个实例,如果它';他打了好几次电话?,javascript,function,multiple-instances,Javascript,Function,Multiple Instances,我已经写了一个自定义动画函数。它通常工作正常,但当我调用animate()时在不同的EndCallback的快速连续中,有时回调会严重重叠,导致在错误的时间执行错误的操作 问题是函数多次实例化并执行,直到达到endValue为止。currentValue更改得太快,以至于我只能看到html页面动画中的最后一个值。这隐藏了这种不想要的行为 调用animate()时需要什么第二次是结束animate()的第一个实例并使用新值和新回调触发一个新值。同时,我想停止setTimeout()函数,以确保不会

我已经写了一个自定义动画函数。它通常工作正常,但当我调用
animate()时
在不同的EndCallback的快速连续中,有时回调会严重重叠,导致在错误的时间执行错误的操作

问题是函数多次实例化并执行,直到达到endValue为止。currentValue更改得太快,以至于我只能看到html页面动画中的最后一个值。这隐藏了这种不想要的行为

调用
animate()时需要什么第二次是结束
animate()的第一个实例
并使用新值和新回调触发一个新值。同时,我想停止
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();
        }
    }
}
而不是在控制台中查看: 1,2,3, - 1,4,2,5 ... 6,9,7,10,8,9,10

我只想看看: 1,2,3, - 1,2 ... 7,8,9,10


但是,请记住,由于我在脚本中使用
animate()
的方式,我不能依赖于知道输入变量的名称或范围。这使我无法自己解决它。

虽然它不是您所要求的实现,但我想知道下划线的节流或去盎司是否能满足需要

将确保每秒调用函数的次数不超过X次——每次调用时仍将执行一次,但后续调用将延迟以满足速率限制。因此,如果您连续快速调用两次animate,则debounce会将第二次执行延迟到第一次执行后100毫秒或其他时间

将基本上忽略在速率限制期间发生的呼叫。因此,如果你在100毫秒内调用你的动画10次,你可以让它扔掉除第一次之外的所有东西。(实际上,它将执行第一个操作,再加上等待期结束时的一个操作)

您不需要使用所有下划线来获取这些方法;我看到人们经常复制和粘贴下划线中的去盎司和/或节流功能。如果你在谷歌上搜索,你可以找到一些独立的节流或去盎司实现

油门和去盎司通常用于动画


对于您最初的规范,实际上“结束animate()的第一个实例”——在javascript中没有非常可靠的方法。没有真正通用的方法来“取消”已经执行的函数。如果你能使它与去盎司或油门工作,我认为这将导致较少的挫折

您需要的是存储上次使用的超时id。因此,下次启动新动画时,可以使用此超时id和
cleartimout

我发现在函数本身上存储间隔很方便

请参见此处的jsbin:


不能从一个函数停止另一个函数的执行。假设您正在使用jquery进行动画,那么有一个
.stop
方法可以调用元素来停止在该元素上运行的任何动画。我需要能够在运行中更改动画对象的状态,因此防止双击对于我来说并不是一个真正的选项。干杯这和我想要的非常接近。对于我的特定用例,它工作得非常好,我可以通过创建一个包含多个setTimeout()的对象来进一步调整此解决方案;多个动画变量的ID。这将有助于在不重置错误对象的动画的情况下设置不同对象的动画。非常感谢你!不客气!看来你可以接受这个答案。请注意,如果执行“很多”(20+??)的动画,setTimeout开销可能会过大,这是您遇到问题的原因。您必须还原逻辑,并在驱动所有动画逻辑的setInterval或requestAnimationFrame上挂接一个处理程序;对于多个画布和页面操作,实际上,它确实通过显著的措施提高了总体性能。我简化了示例代码,以使不需要的行为易于注意。我将替换clearTimeout();使用cancelAnimationFrame();非常感谢您的反馈!
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();
        }
    }
}