ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2020.9.9

2022-09-09 19:30:46  阅读:219  来源: 互联网

标签:const 2020.9 url 歌曲 music 播放 row


首先简单说一下在项目遇到的问题

问题:自己做的是一个音乐播放器,其中用到vuex这个状态管理工具。出现的一个bug就是每当点击某首歌曲进行播放的时候,我在这时获取这首歌的总时长然后渲染在页面上,这个时间总是上一首歌的总时长。

出问题的地方,播放歌曲方法:
问题代码1
updateSongUrl方法时提交到mutation进行更新歌曲url,这里我await修饰getUrl方法执行完(该方法时一个ajax请求),然后更新url,接着直接修改歌曲播放的状态isPlay,下面我又watch监听了这个状态。(看样子感觉没啥问题.....)

问题代码2
在这一刻我watch到歌曲音频时长是上一首歌的时长。很明显,在songUrl还没更新的时候先拿到了上一首歌的时长,这是异步惹得祸。其实第一张图已经给出了解决方案,设置定时器,等待播放歌曲的方法执行完再通知播放,这时候就能正常拿歌曲时长而不是上一首。
个人认为在歌曲的url还没得到更新之前,watch里面的回调方法就开始执行了。在此我上网查了关于async函数,知道在没有 await 的情况下执行 async 函数,它会立即执行,返回一个 Promise 对象,并且,绝不会阻塞后面的语句。那么我可以这么认为在updateSongUrl()还没完成的时候,就继续执行了下面的状态更新方法,从而导致问题的出现。

完整代码:

methods:

async play (row, column, event) {
      // 更新歌曲的播放状态为关闭
      this.updateIsPlay(false)
      const res = await this.$isPlayed(row.id)
      if (!res.data.success) {
        this.$message({
          type: 'info',
          customClass: 'model-message',
          iconClass: '1',
          message: res.data.message
        })
        return
      }
      // 更新歌曲信息
      this.updateSongInfo(row)
      // 获取歌曲Url
      this.url = await getUrl(row.id)
      this.updateSongUrl(this.url)
      // 通知播放
      setTimeout(() => {
        this.updateIsPlay(true)
      }, 300)
      this.updateIsPlay(true)
      // 判断是否重复点击
      let info
      for (let i = 0; i < this.songList.length; i++) {
        info = this.songList[i]
        this.isRepetSong(info)
      }
      // 更新当前播放歌曲在最近播放中的索引
      for (let i = 0; i < this.renList.length; i++) {
        if (row.id === this.renList[i].id) {
          this.songIndex = i
        }
      }
      this.updateSongIndex(this.songIndex)
      console.log('当前歌曲索引:' + this.songIndex)
    }

watch:

// 监听歌曲播放状态
    isPlay (val) {
      // 获取audio音频对象
      const music = this.$refs.music
      if (val) {
        const judge = () => {
          // 获取歌曲的加载状态
          const state = music.readyState
          if (state >= 3) {
            // 获取歌曲时长
            const long = music.duration
            this.allDuration = Math.floor(long)
            // 获取总时长的分
            const minute = Math.floor(Math.floor(long) / 60)
            // 获取总时长的秒
            const second = Math.floor(long) % 60
            // 将转换之后的时间赋值给歌曲的总时间用于展示
            const time = this.getTime(minute, second)
            this.songTime = time
            console.log('歌曲时长:' + this.songTime)
            // 播放音乐
            music.play()
            this.updateIsPlay(true)
            this.isRepetSong()
            console.log('judge触发了,加载状态' + state)
          } else {
            setTimeout(() => {
              judge()
            }, 200)
          }
        }
        judge()
      } else {
        // 暂停音乐
        music.pause()
      }
    }

标签:const,2020.9,url,歌曲,music,播放,row
来源: https://www.cnblogs.com/ushen/p/16673792.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有