目 录CONTENT

文章目录

记录计时器的使用方法

cplinux98
2022-08-30 / 0 评论 / 0 点赞 / 46 阅读 / 1,353 字 / 正在检测是否收录...

00:文章简介

本文介绍了在Vue + element-ui中配置计时器的相关案例。

01:计时器种类

js中的计时器分为两种:setInterval(),setTimeout()

1.1:setInterval

该计时器的作用为:按照指定的周期(单位毫秒)来调用函数,该方法会一直执行下去,是个死循环,除非使用clearInterval()来清除函数或关闭浏览器窗口。

setInterval(code, millisec, lang)

code: 必须,要调用的函数,不能带参数
millisec: 必须,以毫秒为单位的时间间隔
lang: 可选,选择语言

例子:

const id=setInterval(foo, 5000) // 开始,每隔5s钟运行一次
clearInterval(id)  // 停止

1.2:setTimeout

该计时器的作用为:在指定的时间(单位毫秒)后调用函数,单次执行,若要多次执行,需要使用递归。

setTimeout(code, millisec, lang)

code: 必须,要调用的函数,不能带参数
millisec: 必须,以毫秒为单位的时间间隔
lang: 可选,选择语言

例子:

var num = 0;
function startCount(){
    console.log(num)
    num += 1;
    setTimeout(startCount,1000);    //setTimeout是超时调用,使用递归模拟间歇调用
}
setTimeout(startCount,1000);    //1s后执行

02:setInterval计时器中使用带参函数

function foo(a, b) {
    console.log(a + b)
}
setInterval(foo(1, 2), 3000)


// 此时会运行一次并出现一个错误
internal/validators.js:224
    throw new ERR_INVALID_CALLBACK(callback);
    ^

TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined

可以使用匿名函数来运行带参数的函数

function foo(a, b) {
    console.log(a + b)
}

setInterval(() => {
    foo(1, 2)
}, 3000)

这就达到了我们定时调用函数的目的

03:setInterval计时器案例之定时刷新列表内容

在前端项目中,我们经常会遇到需要定时刷新列表内容类似的功能,下面是以vue + element-ui中,table组件定时刷新,并实现☑️后,再刷新会根据上次☑️条目是否存在,保持☑️状态。

3.1:配置table组件

目标:列表是实时动态刷新的,实现条目☑️后,即使列表刷新,也保持☑️状态

思路:使用table原生属性,但selection中不会自动判断里面的条目是否还有效

// 列表内容
<el-table 
ref="multipleTable"
:data="hostList"
row-key="mac" 
border 
style="width: 100%">
        <el-table-column type="selection" :reserve-selection="true" width="45"> </el-table-column>
</el-table>

关键属性:
ref: 可以通过this.$refs.refValue去调用该table
row-key: 设置每行的唯一id,选中后,会将选中的row对象存在table.selection属性中,也就是this.$refs.multipleTable.selection
reserve-selection="true": 设置刷新后,重新按照row-key记录的值进行选中

3.2:实现判断逻辑

目标:☑️后,再刷新会根据上次☑️条目是否存在,清除无效条目

思路:在getList方法中,使用数组的循环来对比每一个选中过的值,是否存在于新获取的列表中

   async getList() {
      const { data: response } = await this.$http.get('test')
      if (response.code) {
        return this.$message.error(response.message)
      }
      this.hostList = response.results
      if (this.$refs.multipleTable.selection.length !== 0) { // 如果选中列表为空,则不判断
        this.$refs.multipleTable.selection.forEach((row) => { 
           // 遍历选中列表,使用json去判断是否存在,如果存在返回值是索引位置,如果不存在,返回值为-1,则删除掉该元素
          if (JSON.stringify(this.hostList).indexOf(JSON.stringify(row)) === -1) {
            this.$refs.multipleTable.selection.splice(this.$refs.multipleTable.selection.indexOf(row), 1)
          }
        })
      }
    }

3.3:计时器配置

把计时器封装为一个函数,可以通过该函数配置计时器的启动与结束

cycleRunFunc(status, func, time) {
      if (status) {
        // start == 1
        this.intervalID = setInterval(func, time)
      } else {
        // stop == 0
        clearInterval(this.intervalID)
        this.$message.success('已停止自动刷新,刷新页面后继续自动刷新')
      }
    }
    
// 开启计时器 cycleRunFunc(1, foo, 3000)
// 关闭计时器 cycleRunfunc(0)

3.4:遇到的问题

遇到了:vue路由切换后,计时器仍继续工作,后来根据vue的生命周期,发现可以使用切换时销毁的回调函数来帮助我们在切换路由后,终止计时器的工作。

  beforeDestroy() {
    if (this.intervalID) {
      clearInterval(this.intervalID)
    }
  },

04:设置多个定时任务

const timerManager = {
    // func1: 1  先创建一个记录定时任务ID的对象
}

function cycleFunc(status, func, time) {
    const funcName = func.name
    if (status) {
        // set and record
        const intervalID = setInterval(func, time) // 开始运行后,将函数名称作为key,ID作为value存储在上面的对象中
        timerManager[funcName] = intervalID
    } else {
        // clear
        console.log('stop start +++++++++++++++++++++++++')
        const intervalID = timerManager[funcName] // 删除前,从对象中通过函数名称获取value,也就是id
        console.log(intervalID)
        clearInterval(intervalID)
        delete timerManager[funcName] = undefined
        console.log('stop end +++++++++++++++++++++++++')
    }
}

function foo1() {
    console.log('start 11111')
}

function foo2() {
    console.log('start 222222')
}

// 运行模拟函数
cycleFunc(1, foo1, 3000)
cycleFunc(1, foo2, 5000)

// 提前设置好停止函数
function one() {
    console.log('foo1 is top')
    cycleFunc(0, foo1)
    console.log(timerManager)
}

function two() {
    console.log('foo2 is top')
    cycleFunc(0, foo2)
    console.log(timerManager)
}

setTimeout(one,10000);    //10s后执行
setTimeout(two,20000);    //20s后执行

最后的效果为:

start 11111
start 222222
start 11111
start 11111
foo1 is top
stop start +++++++++++++++++++++++++
stop end +++++++++++++++++++++++++

start 222222
start 222222
foo2 is top
stop start +++++++++++++++++++++++++
stop end +++++++++++++++++++++++++

0

评论区