马上过年了,今年是马年,那可真是“马”上哦,加上最近感冒了,我们v1.0.9版本,就讨个巧,以截至目前历史版本中最小的代码量,补齐一个大的功能拼图--随机播放。为什么只要10行的代码,就实现了随机播放?且听我细细道来。老朋友都知道,早在v1.0.4版本,我们就实现了播放模式的界面,虽然当时还没有实现列表,仅支持“单曲循环”,但预留了“顺序播放”和“随机播放”的界面按钮,说明我们是志存高远的。又在后续版本实现了顺序播放功能,并解决了定时器重启的bug。一、改动:只加 10 行代码!
大家可能以为和顺序播放一样,需要重构整个运行逻辑,但得益于我们前期良好的架构设计,我们只需要做很小的改动即可。在原来的SINGLE_LOOP和SEQUENTIAL分支后面,新增一个RANDOM分支:// v1.0.9 新增:随机播放处理逻辑else if (this.playMode === PlayMode.RANDOM) { console.info('执行随机播放,随机选择下一首'); if (this.audioList.length > 0) { // 生成随机索引(0 到 length-1) const randomIndex = Math.floor(Math.random() * this.audioList.length); this.updateStatus(`随机播放,下一首: ${this.audioList[randomIndex].name}`); // v1.0.8 风格:自动切换不重置倒计时 this.playAudioByIndex(randomIndex, false); } else { this.updateStatus('播放列表为空,无法继续播放'); this.playerState = PlayerState.COMPLETED; await this.releasePlayer(); this.clearCountdown(); }}
细心又帅气的朋友可能已经发现了,和顺序播放相比,只是把调用playAudioByIndex的index参数,从index+1,修改为随机生成的index值。需要注意的是,因为随机播放也是自动切换音乐,所以是否重启倒计时的参数值,仍然传入false,也就是这行代码。
// v1.0.8 风格:自动切换不重置倒计时 this.playAudioByIndex(randomIndex, false);
这都是因为之前版本都做了充分的准备,枚举值,按钮等,都已经预留。UI之前也支持点击“随机播放”按钮,只是后台代码处理的时候会把它作为ELSE理解,进入else分支。我们这次相当于给一条已经画好的龙,点上了眼睛。可见良好的设计理念:如UI和逻辑分离,可以让后续的功能扩展更轻松,也更有利于实现团队合作开发。二、关于随机数函数:Math.random()
先看代码:
const randomIndex = Math.floor(Math.random() * this.audioList.length);
定义了一个常量(Const表示常量)randomIndex,给他赋了一个从0到index-1的随机数。其中Math.random()会生成一个0~1之间的随机小数,比如0.618;而*this.audioList.length),则会将小数值放大到列表长度,也就是我们乐曲的个数这个范围,假定有8首歌,则0.618*8=4.944;最外面的Math.floor()则表示对计算结果进行向下取整。4.944向下取整后结果为4,就会播放第5首歌,没错吧?还记得数组的索引是从0开始的哦。这样就能保证每个索引被选中的概率完全相等,也就是真随机。什么?您说实际是伪随机,因为根子里面的math.random就是伪随机数,没错,您说的对。总结:v1.0.9版本实现了随机播放功能,让下一首歌的到来,就像盲盒一样,有着意外的惊喜,有没有拆快递的期待感呢?也像阿甘说的那盒巧克力,你永远不知道下一颗是什么味道,但肯定是美味的。E智音频播放器的下一个版本,以及本号的下一篇学习记录,虽然目前还不确定版本改进的方向,但肯定是有改进的。最后,预祝朋友们新年快乐!马年大吉!骐骥驰骋!大展宏图!