带有一个函数的多个setIntervals(Javascript)

时间:2017-06-16 02:35:31

标签: javascript function setinterval

此代码随机播放音频元素。运行setup两次允许您同时使用两个不同的阵列,这就是我想要的。问题是#stop只停止其中一个阵列播放。如果您只在一个阵列上调用setup,但多次点击#start(我也不想要),也会发生这种情况。我认为这与'intervalReturn'有关,因为它只会指定给一个setInterval

我该怎么写这个,以便setup的多次调用创建不同的setIntervals,只能启动一次?

或者,如果我从一个完全不同的角度来看待这个问题,那会更好吗?

编辑:这是根据以下建议修复的。但是我想知道,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);
}); 

1 个答案:

答案 0 :(得分:1)

  

但我想知道,发生了什么事情"引擎盖下"在这里使用setInterval?

每次拨打setup()时,都会在#start#stop元素上创建其他点击处理程序。当您实际点击#start#stop时,会调用适用处理程序的所有(按照绑定的顺序)。这就是为什么点击#start会导致CMajor3 CMajor4注释发挥作用的原因。您将获得多个并发但不相关的间隔。

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

var intervalReturn函数中移动setup()声明会有所帮助,因为closures work in JS的参数和局部变量setup()的方式,即timepitchSetintervalReturn(在您移动声明之后)可以在当前调用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()之后可能会更多. v 68.915850808760979 eval {set sim_annotation {1 received {how are you}}} . v 68.915850808760979 eval {set sim_annotation {question: how are you. answer: fine}} . v 70.508104551724557 eval {set sim_annotation {0 received {hi}}} . v 70.508104551724557 eval {set sim_annotation {question: hi. answer: Thanks}} ,以便它记录刚刚返回的间隔ID,而不是之前的。这样你就可以看到所有相关变量的值,看看发生了什么。