在看了一些关于HTML5 Audio API的资源后,一下子热情高涨顺势写了个音乐频谱效果的作品来玩味,也就是上上篇博文里介绍的。今天在测试的时候发现三个问题处理得不是很好:
鉴于后面的内容是跟具体程序有关的(上上篇博文中介绍的Audio Visualizer),所以不知道源码的你或许不太感兴趣,于是把结论提前。
我想说的就是, 在JavaScript中递归使用了setTimeout或者setInterval,或者requestAnimationFrame(这个方法本身要求你递归使用),如果你的代码有结束条件,最好在递归满足结束条件后调用clearTimeout/clearInterval,cancleAnimationFrame来结束这些方法的运行。
就比如在问题三当中,我用的requestAnimationFrame来写的动画,当歌曲播放完毕,调用cancleAnimationFrame来清理之前设置的requestAnimationFrame以释放内存。
下面是个关于取消requestAnimationFrame的简单例子,来自css-tricks:
var globalID; function repeatOften() { $("<div />").appendTo("body"); globalID = requestAnimationFrame(repeatOften); } $("#start").on("click", function() { globalID = requestAnimationFrame(repeatOften); }); $("#stop").on("click", function() { cancelAnimationFrame(globalID); });
第一个问题是用户体验的问题,很好解决,所以对于页面顶部的infobar作了如下调整:
第二个问题,出乎我的意料,同时也想不通,不妨先来重现一下。
下图便是播放bbc_sherlock_openning.mp3完毕后的画面,程序就这样停留在了这样的一个画面,有三根频谱条没有归零。我硬盘里大部分歌曲都被我跑过了都没问题,但才看了<神探夏洛克>的我执意要拿它的片头曲来爽一把,然后就发现问题了。
我不认为是程序的问题,又无奈想不出这文件有什么问题,于是只能来硬的了。进行人工干预,在每首歌曲播放完毕后手动将从歌曲里面获取的值也就是analyser设为0,这样所有频谱条都会没有问题了。算是个笨拙的解决方法吧,因为没有打到问题的根源。
具体代码可以去下载最新版本的源码查看。之前的代码都有注释,后来加的这些注释不详细,所以我自认为有点晦涩难懂。
对于第三个问题,其实原因我知道,也知道如何解决,只是在创建程序时没有好的方案来组织代码避免其他问题。今天再次进行编码时得到了解决。
解决之前,不妨先来看开发者工具中显示的信息。
这是歌曲播放过程中,还看不出什么端倪。等待歌曲结束继续观测。
从上图可以看出,即使歌曲结束,内存还是呈现规律地起伏,我们期望的是它稳定,并且上方的记录数随时间推进也在增加,说明后台代码正在运行。
原因是代码中使用了requestAnimationFrame设置动画,并且每选择一首歌后,都又会重新建立新的requestAnimationFrame来进行动画,而前面的requestAnimationFrame没有消失仍然存在,这样一来,一首接一首的歌曲后可以预见到浏览器崩溃的情况。
解决方法也就是前面说的适时地调用cancelAnimationFrame来清理之前设置的动画。
下图展示了改进后的情况。可以看到,歌曲播放完毕后,记录数停止了增加,说明后台代码没有再运行了,并且等待了一段时间后图中的内存也处于稳定状态,没有起伏。
原文:http://www.cnblogs.com/Wayou/p/cancleAnimationFrame.html