vue 使用两个setInterval 出现混乱

现在的业务需求是:1. 定时刷新页面,因为数据库数据可能会更新 2. 页面滚动展示,只展示6条数据 

我的思路是:1. 设置第一个定时器自动刷新页面 2. 设置第二个定时器改变列表数据,移走前六条加到列表末尾,每次只展示前六条

created() {
        this.getData();
        this.play();
    },
    methods: {
        getData() {
            // 取数据
        },
        play() {
            setInterval(this.getData, 7000);
            setInterval(this.change, 3000);
        },
        change() {
            if(this.dataList.length > 6){
                for (let i=0; i<6; i++){
                    this.dataList.push(this.dataList[i])
                    this.dataList.shift()
                }
            }
        }
    }

但是会混乱,就是getData根本不是用的7s,而是3s
请问该如何解决呢,谢谢!

 

补充问题:这样的模式是因为这个页面是要用作投影的,就是几乎不会有用户去自动刷新……

也就是说现在的流程是:打开页面,展示第一波六条数据、再展示下一波的六条数据,所以我需要动态展示六条数据,ok过一会儿刷新刷新数据库,因为数据库会有新增,这个时间肯定会等待得长一点

获取数据7s是肯定没错的,混乱是因为你的change有问题。你的代码是shit移除第一个后,第二个跑第一位,而你的i++又操作下一个了,导致原来2,4,6,8这种位置的数据被删除了,而使用下一个位置的数据替换,多次执行后会导致出现重复的数据

 

要轮流显示应该每次都是操作第一个数据项,因为shift后下一个数据跑第一位了

            if(this.dataList.length > 6){
                for (let i=0; i<6; i++){
                    this.dataList.push(this.dataList.shift())//可以直接合并为一句就行,shift会返回第一个元素,直接压如最后                    
                }
            }

 

为什么用两个定时器呢,就用一个就能完成你的需求。两个定时器先运行的是change事件哎,再运行getData事件

created() {
        this.getData();
        this.play();
    },
    methods: {
        getData() {
            // 取数据之后再改变
             this.change();
        },
        play() {
            setInterval(this.getData, 7000);
             
        },
        change() {
            if(this.dataList.length > 6){
                for (let i=0; i<6; i++){
                    this.dataList.push(this.dataList[i])
                    this.dataList.shift()
                }
            }
        }
    }

或者

created() {
        this.getData();
        this.play();
    },
    methods: {
        getData() {
            // 取数据之后再改变
            
        },
        play() {
            setInterval(()=>{
               this.getData();
               this.change();
             }, 7000);
             
        },
        change() {
            if(this.dataList.length > 6){
                for (let i=0; i<6; i++){
                    this.dataList.push(this.dataList[i])
                    this.dataList.shift()
                }
            }
        }
    }

 

思路:

1.页面初始化时候启动getData方法,拉数据并渲染,定时7s后重新执行该方法

2.渲染时只展示前6条即,多余的不用处理

问题:

1.你搞了两个定时任务,有可能数据还没拉到最新的,就开始改变页面了

2.change方法有问题啊,dataList.length<6 你这个不就废了。不要在遍历数组的时候数组

给你个伪代码吧

    created() {
        this.getData();
    },
    methods: {
        getData() {
            //1. ajax 从服务端拉去数据, 2.success 时,将结果赋值给this.dataList
            
            //2.在模板渲染时 v-for,索引值<6才展示,此处不处理数据

            //3. 7s后重新执行次方法
            setTimeout(()=>{
                this.getData()
            },7000)
        }
    }

 

这样没意义,定时刷新,如果是整个页面的话,影响用户体验,用ajax刷新某个区域的话,会面临这样一个问题:用户操作数据,比如对数据进行修改,或者删除之类的,由于设置了定时强制刷新,导致操作失败,数据库虽然更新,但是用户打开页面就相当于一次页面刷新,同时也就伴随着从数据库从新拿新的数据,用户删除,或者修改后可以自动刷新某个部分,实现数据实时更新吧,每页显示6条,可以用分页。在说说你的需求,你是想让数据在一个页面用轮播的上下滚动,vue有对应的前端框架格式,实现无限滚动,页面只显示自己设定的几条数据

相关代码

<template>
  <ul class="infinite-list" v-infinite-scroll="load" style="overflow:auto">
    <li v-for="i in count" class="infinite-list-item">{{ i }}</li>
  </ul>
</template>

<script>
  export default {
    data () {
      return {
        count: 0
      }
    },
    methods: {
      load () {
        this.count += 2
      }
    }
  }
</script>

 

是怎么处理的呢 ? 我也遇到了这个问题