所以我正在构建一个带有html5的新<Audio>
标签的音频播放器,但我在javascript(See example here)中声明,初始化和操作<Audio>
序列。 <Audio>
标签一次只允许播放一首歌并轻松操作,因此每当“下一步”,“上一首”,“随机播放”或甚至只是选择另一首歌时,我都会替换{带有新网址的音频标记的{1}},包含新歌。
加载后,我将变量src
声明为:
song
所有其他选定的歌曲只是覆盖了var song= new Audio("url");
,如此:
song
该方法已经结束,但对于每个歌曲实例,事件处理程序监视诸如用于清理的range之类的事件及其属性song= new Audio("new url");
,它确定范围的长度和值确定索引落在范围上的位置与max
的每个先前实例相关联。我不得不重新分配事件监听器并每次重新分配这些属性,在一定数量的歌曲之后,性能确实开始受到影响。
我的问题是,即使javascript有一个垃圾收集器,目标内存不再使用,song
的实例都有与之关联的全局事件监听器,所以我认为它们不会被自动删除。一旦歌曲被覆盖,有没有办法删除它们?是否有完全不同但更好的方法来实现我想要的东西?
感谢您提供任何帮助和建议!
答案 0 :(得分:1)
我决定对问题采取不同的方法,以便完全避免垃圾收集问题。虽然这不一定是我问题的直接答案,但它是一种替代的,有效的解决方案。
我最终只是简单地重新分配audioInstance.src
,假设用新的实例覆盖每个Audio
实例,其中包含一个新的网址src
。最初,歌曲无法播放,或者涉及元数据的自动播放器的某些部分无效,但我找到this链接,这说明您必须先调用audio.load();
当您更改{{ 1}}。
此:
audio.src
而不是:
var audio = new Audio(url);
addListeners(); //only need to do this once, since the listeners always point to audio declared above
var duration=audio.duration;
audio.play();
audio.src = newurl;
audio.load();
duration=audio.duration;
audio.play();
这帮助我达到了我想要的最终结果,摆脱了为var audio = new Audio(url);
addListeners();
var duration=audio.duration;
audio.play();
audio = new Audio(newUrl);
addListeners(); //need to do this a second time, since the old listeners will always be attached to the old audio instance
duration=audio.duration;
audio.play();
对象的多个实例声明多个侦听器时出现的垃圾收集问题。
答案 1 :(得分:0)
一旦变量不在范围内,变量将被垃圾收集。 关于全局变量的糟糕之处在于它们永远不会有资格进行垃圾回收。我最好的建议是避免全局变量,并始终将范围限制在所需的范围内