javascript - 使用一个函数进行多个 setIntervals (Javascript)

标签 javascript function setinterval

此代码随机播放音频元素。运行 setup 两次可以让您同时对两个不同的数组执行此操作,这就是我想要的。问题是 #stop 仅停止其中一个数组的播放。如果您只在一个数组上调用 setup,但多次单击 #start(我也不希望出现这种情况),实际上也会发生这种情况。我认为这与“intervalReturn”有关,因为它只能指定为一个 setInterval

我应该如何编写此代码,以便多次调用 setup 创建只能启动一次的不同 setIntervals?

或者,如果我应该从完全不同的 Angular 来处理这个问题,什么会更好?

编辑:此问题已根据以下建议修复。但我想知道,这里 setInterval 的“幕后”到底发生了什么?为什么会发生这种行为? (具体来说:#stop 停止一个但不是所有音频元素。)

var CMajor3 = new Array ("C3","D3","E3","F3","G3","A3","B3","C4a");
var CMajor4 = new Array ("C4b","D4","E4","F4","G4","A4","B4","C5");

var intervalReturn = null;  

function pickAndPlay(pitchSet){
    fyshuffle (pitchSet);  // the Fischer-Yates shuffle function
    var tone = document.getElementById(pitchSet[0]);
    tone.currentTime = 0;
    tone.play();    
};

function setup(time, pitchSet){
    $("#start").click(function() {   
        console.log("startClicked"); 
        intervalReturn = window.setInterval(pickAndPlay, time, pitchSet)
    }); 
    $("#stop").click(function() {   
        console.log("stopClicked");  
        window.clearInterval(intervalReturn)
    }); 
};  

$(document).ready(function() {  
    setup(2000, CMajor3);
    setup(2000, CMajor4);
}); 

最佳答案

But I'm wondering, what is going on "under the hood" with setInterval here?

每次您调用 setup() ,这会在 #start 上创建额外点击处理程序和#stop元素。当您实际单击#start时,或#stop所有所有适用的处理程序都会被调用(按照它们绑定(bind)的顺序)。这就是为什么点击 #start导致 CMajor3 CMajor4演奏的音符。您会运行多个并发但不相关的间隔。

intervalReturn定义为全局变量,您只能拥有最近一次调用 setInterval() 返回的间隔 ID。 ,因为每次#start单击处理程序运行它会覆盖前一个。这就是为什么点击 #stop只能停止其中一个间隔,而无法停止其他间隔。

移动var intervalReturn setup()内的声明功能有帮助,因为方式 closures work in JSsetup() 的参数和局部变量,即time , pitchSetintervalReturn (在移动声明之后)可以在对 setup()当前调用中定义的两个事件处理程序中进行访问。 。随后调用setup()使用这些变量自己的单独副本创建新的闭包。那么#stop单击处理程序使用单独的 intervalReturn与其自身相关setup() 。并且因为 #stop处理程序运行,两个间隔都被清除。

但是您仍然遇到点击 #start# 的问题多次未点击#stop创建额外的间隔,然后在任何一个 setup() 内那个人intervalReturn被最新的覆盖,所以再次 #stop无法引用之前的时间间隔。这就是为什么添加 if (intervalReturn === null)#start如果尚未运行一个时间间隔,则处理程序有助于启动一个新的时间间隔。 (然后您需要在 intervalReturn = null 处理程序中添加 #stop,因为仅调用 clearInterval(intervalReturn) 不会更改 intervalReturn 变量的值。)

建议:更新您现有的 console.log()声明如下:

console.log("startClicked", pitchSet, intervalReturn); 
// and
console.log("stopClicked", pitchSet, intervalReturn); 

也许更多的是 startClicked调用 setInterval() 后立即调用一这样它就会记录刚刚返回的间隔 ID,而不是前一个间隔 ID。这样您就可以看到所有相关变量的值并了解发生了什么。

关于javascript - 使用一个函数进行多个 setIntervals (Javascript),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44579911/

相关文章:

JavaScript 表单验证不适用于所有 HTML 字段

php - 在 PHP 函数中嵌套 PHP 函数。不好的做法?

javascript - 停止带有 promise 的 $interval 函数

javascript - HTML:当条件不再成立时,如何使条件消息消失?

swift - 如何从方法内部更新类变量,以便该变量对 Swift 中的其他类可见?

javascript - 如何修改 setInterval 代码以最初触发间隔操作

javascript - setInterval/setTimeout 检查变量值

javascript - 如何在 Blogspot 模板中创建一个使用 Blogspot 变量的脚本?

javascript - 如何使 fancybox href 动态化?

javascript - 如何使用文件哈希或使用它使用 Node JS 将文件下载到服务器