vue2 clearInterval失效问题(针对于多条正向计时问题)?

作者站长头像
站长
· 阅读数 14

前情提要:有个项目需要添加语音沟通,每一条语音进来后都需要从00:00:00开始计时,开发过程中出现了问题,就是window.setInterval是好使的,但是重置window.clearInterval失效,在当前页面可clearInterval好使,但切换页面后再重新回来重置clearInterval就失效了,麻烦大神们帮忙看下啥问题(当前页面路由有keepAlive为true)注:点击挂断会挂断当前这条语音然后置为00:00:00,其他语音之间互不影响会继续之前的计时

<script>
export default {
  name: 'order',
  data() {
    return {
      orderList:[]
     }
  },
computed: {
      ...mapGetters([
        "eventType",
      ])
    },
  watch: {
      //监听状态
       eventType(val, oldVal) {
        if (val == "EVENT_HANGUP") {
          //挂断操作
             this.hangUpHandle('voice');
        }
        if (val == "EVENT_ANSWER") {
         //接听操作
          this.getListHandle();//获取当前语音数据
          this.formatDuring();//开始计时
        }
      },
  },
  methods:{
     getListHandle(){
         //调用接口获取当前(条)语音
          let params = { number:number };
          getByData(params).then((response) => {
            let date = dateFormat(new Date());
            let newArr = [
              {
                name:response.data.customer.name,
                tagName: "telephone",
                icon: "el-icon-dianhua-yuankuang",
                durationTime: "00:00:00",
                createTime: date,
                ifHangUp:false,
                flag: null,
                hour: 0,
                minute: 0,
                second: 0,
                time: "00:00:00",
                source:'voice'
              },
            ];
            this.orderList = newArr; //当前只有一条每次接听会push一条数据
            window.localStorage.setItem("orderList", JSON.stringify(newArr));
            this.formatDuring();
          });
     },
     formatDuring(val) {
        //针对于多条正向计时
        let newArr = JSON.parse(JSON.stringify(this.orderList));
          newArr.map((item) => {
            if(item.ifHangUp==false){
                item.flag=window.setInterval(() => {
                    item.second = item.second + 1;
                    if (item.second >= 60) {
                    item.second = 0;
                    item.minute = item.minute + 1;
                    }
                    if (item.minute >= 60) {
                    item.minute = 0;
                    item.hour = item.hour + 1;
                    }
                    item.time =
                    this.complZero(item.hour) +
                    ":" +
                    this.complZero(item.minute) +
                    ":" +
                    this.complZero(item.second);
                   //template里面展示的字段为durationTime
                    this.$set(item, "durationTime", item.time);
                    window.localStorage.setItem("orderList", JSON.stringify(newArr));
                }, 1000);
             }else{
                item.hour = 0;
                item.minute = 0;
                item.second = 0;
                item.time = "00:00:00";
                item.flag=null;
                window.localStorage.setItem("orderList", JSON.stringify(newArr));
             }
            this.orderlist = newArr;
            this.$forceUpdate();
          });
      },
      hangUpHandle(val){
          //针对于多条挂断
          let newArr = JSON.parse(JSON.stringify(this.orderList));
          if(val){//条件挂断
            newArr.map((item) => {
                if(item.source==val){
                    //清除
                    window.clearInterval(item.flag);
                    this.clearIntervalHandle(item,newArr,'single');
                }
            });
          }else{//全部挂断
            newArr.map((item) => {
                   //清除
                   window.clearInterval(item.flag);
                  this.clearIntervalHandle(item,newArr,'all');
            });
          }
          this.$forceUpdate();
      },
      clearIntervalHandle(item,newArr,tag){
        item.hour = 0;
        item.minute = 0;
        item.second = 0;
        item.time = "00:00:00";
        item.flag=null,
        item.ifHangUp=true,//判断当前是否挂断
        this.$set(item, "durationTime", item.time);
        window.localStorage.setItem("orderList", JSON.stringify(newArr));
        this.orderList= newArr;
        if(tag==='single'&&this.orderList.length>1){
            this.formatDuring();
        }
        this.$forceUpdate();
      },
       //补零
      complZero(n) {
        return n < 10 ? "0" + n : "" + n;
      }
   }

}
</script>
回复
1个回答
avatar
test
2024-07-17

一般来说定时器无法清除的问题主要是以下 2 点造成的:

  1. 存储的定时器没有清除,被后来的新定时器覆盖了key,造成无法清除上一个定时器;
  2. 存储的定时器key的变量作用域不正确,导致每一次赋值的key的变量都是新变量。

你这个明显就是第一种,如果要重复创建定时器的,请保证每一次创建并赋值之前都清理掉前一个定时器。

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容