无论何时,记得做好代码的清理工作

简介: 在看了一些关于HTML5 Audio API的资源后,一下子热情高涨顺势写了个音乐频谱效果的作品来玩味,也就是上上篇博文里介绍的。今天在测试的时候发现三个问题处理得不是很好: 当歌曲正在播放的时候再选择另一首,页面顶部的标题没有很好地更新 对于有些音频文件,比如在上篇博文中提供的示例音乐里面,bbc_sherlock_openning.mp3这个文件在播放完毕后频谱居然不会归零! 另一个问题就是重点了,歌曲播放完了后后台代码仍在不停地跑 结论 鉴于后面的内容是跟具体程序有关的(上上篇博文中介绍的Audio Visualizer),所以不知道源码的你或许不太感兴趣,于是把结论提前。

在看了一些关于HTML5 Audio API的资源后,一下子热情高涨顺势写了个音乐频谱效果的作品来玩味,也就是上上篇博文里介绍的。今天在测试的时候发现三个问题处理得不是很好:

  1. 当歌曲正在播放的时候再选择另一首,页面顶部的标题没有很好地更新
  2. 对于有些音频文件,比如在上篇博文中提供的示例音乐里面,bbc_sherlock_openning.mp3这个文件在播放完毕后频谱居然不会归零!
  3. 另一个问题就是重点了,歌曲播放完了后后台代码仍在不停地跑

结论

鉴于后面的内容是跟具体程序有关的(上上篇博文中介绍的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);
});

 

Question 1

第一个问题是用户体验的问题,很好解决,所以对于页面顶部的infobar作了如下调整:

  1. 程序开始显示程序名称"HTML5 Audio API showcase | An Audio Viusalizer"
  2. 用户选择文件或者拖拽文件到页面后,显示相应的后台操作,比如"文件上传中。。。","文件解码中。。。",etc.
  3. 途中出错则显示相应错误信息,比如"!解码失败",如果一切顺利,则音乐开始播放并显示当前播放的文件名,同时将文字淡下去,让主题频谱更好地呈现
  4. 歌曲顺利结束,顶部信息恢复正常显示,同时更新标题到最开始状态,也就是显示程序名
  5. 如果歌曲播放过程中用户选择了另外的文件,顶部信息恢复正常显示并且转到步骤2

Question 2

第二个问题,出乎我的意料,同时也想不通,不妨先来重现一下。

下图便是播放bbc_sherlock_openning.mp3完毕后的画面,程序就这样停留在了这样的一个画面,有三根频谱条没有归零。我硬盘里大部分歌曲都被我跑过了都没问题,但才看了<神探夏洛克>的我执意要拿它的片头曲来爽一把,然后就发现问题了。

我不认为是程序的问题,又无奈想不出这文件有什么问题,于是只能来硬的了。进行人工干预,在每首歌曲播放完毕后手动将从歌曲里面获取的值也就是analyser设为0,这样所有频谱条都会没有问题了。算是个笨拙的解决方法吧,因为没有打到问题的根源。

具体代码可以去下载最新版本的源码查看。之前的代码都有注释,后来加的这些注释不详细,所以我自认为有点晦涩难懂。

Question 3

对于第三个问题,其实原因我知道,也知道如何解决,只是在创建程序时没有好的方案来组织代码避免其他问题。今天再次进行编码时得到了解决。

解决之前,不妨先来看开发者工具中显示的信息。

  1. 选择文件进行播放
  2. F12打开高度工具,切到时间轴(Timeline)面板,选择内存(memory)
  3. 点击'记录按钮(Record)' 开始监视代码执行过程中的内存及运行状况

这是歌曲播放过程中,还看不出什么端倪。等待歌曲结束继续观测。

 

从上图可以看出,即使歌曲结束,内存还是呈现规律地起伏,我们期望的是它稳定,并且上方的记录数随时间推进也在增加,说明后台代码正在运行。

原因是代码中使用了requestAnimationFrame设置动画,并且每选择一首歌后,都又会重新建立新的requestAnimationFrame来进行动画,而前面的requestAnimationFrame没有消失仍然存在,这样一来,一首接一首的歌曲后可以预见到浏览器崩溃的情况。

解决方法也就是前面说的适时地调用cancelAnimationFrame来清理之前设置的动画。

下图展示了改进后的情况。可以看到,歌曲播放完毕后,记录数停止了增加,说明后台代码没有再运行了,并且等待了一段时间后图中的内存也处于稳定状态,没有起伏。

目录
相关文章
|
7天前
|
程序员 测试技术
程序员的“Bug之旅”:为何无法一次性写出完美代码?
程序员在软件开发过程中难以一次性写出完美代码,需要不断修改和调试,即“改Bug”,这是由多个因素共同作用的结果。技术层面的复杂性、管理和流程上的不足以及个人能力和认知的局限性都是导致这一现象的重要原因。然而,这并不意味着无法避免或改进。通过加强需求管理、建立有效的版本控制和测试机制、推动团队知识共享以及鼓励代码审查和自我反思等措施,可以降低改Bug的频率和成本,提高软件开发的效率和质量。辩证地看待这一问题,既要理解其存在的合理性,也要积极寻求改进之道,以实现更好的产品和服务。
11 2
|
20天前
|
算法 程序员
为何程序员在编写程序时难以一次性将所有代码完美无瑕地完成,而是需要经历反复修改Bug的过程?
为何程序员在编写程序时难以一次性将所有代码完美无瑕地完成,而是需要经历反复修改Bug的过程?
17 7
|
2月前
|
测试技术
如何做好测试执行工作?
如何做好测试执行工作?
|
8月前
不是工作不好找,是你真的不行
不是工作不好找,是你真的不行
|
前端开发
前端工作小结12-工具里面代码提交
前端工作小结12-工具里面代码提交
56 0
前端工作小结12-工具里面代码提交
|
测试技术
软件测试2个月能学会吗 找到基础的测试工作还是没问题
软件测试2个月能学会吗,相信这是很多想要学习软件测试的人想要知道的问题了吧,今天小编就来给大家说一说,2个月到底能不能学会软件测试。
260 0
软件测试2个月能学会吗 找到基础的测试工作还是没问题
|
JSON 数据可视化 JavaScript
开发改了接口,经常忘通知测试,有什么好的解决方案吗?
不知道大家有没有同感,做接口测试麻烦的不是测试本身,而是接口它会变,更麻烦的不是接口变了,而是它变了而你不知道。等到你测完,开发才悠悠跟你说——“那个接口我改了点东西,你再看一眼哈”。
开发改了接口,经常忘通知测试,有什么好的解决方案吗?
|
消息中间件 Kafka
万字长文解析删除Topic流程领导再也不用担心我排查生产环境问题了(附教学视频,建议收藏!!!)
万字长文解析删除Topic流程领导再也不用担心我排查生产环境问题了(附教学视频,建议收藏!!!)
万字长文解析删除Topic流程领导再也不用担心我排查生产环境问题了(附教学视频,建议收藏!!!)
讨论:有多少项目是因为程序的原因而失败的
导读:外刊IT评论翻译了一篇《关于程序成本的讨论》以下是文章全部内容: 昨天在#SCNA(北美2010软件技术大会)的一个专题小组讨论会上,@chadfowler 提出了这个问题:”有多少项目是因为程序的原因而失败的?“我想,他是想说造成项目失败的主要原因是业务问题,而非技术问题。
1046 0
|
Java 程序员 应用服务中间件
程序员到了 35 岁,还能找到工作吗?
国庆闲聊,程序员真的吃青春饭吗? 由于互联网的蓬勃发展,科技技术的不断迭代更新,中国的互联网行业已经步入的世界的前列,因为,我们常常能看到,在各种各样的报道中,程序员都会誉为未来最有发展潜力的职业之一。
1415 0