定时器基本介绍

436 阅读4分钟

在日常的开发中,有时候我们需要代码延迟一会执行一次(setTimeout),或者每段时间执行一次(setInterval)

1.setTimeout使用场景

image.png

1.2.定义setTimeout的基本语法:

// setTimout会返回一个数字,表示当前延迟器的标记值
let 变量 = setTimeout(需要运行的函数,延迟时间单位毫秒)

//举例:
let timeId = setTimeout(()=>{
  console.log('我被执行了') // ✨✨✨只执行一次
} , 1000)

说明:其中的timeIdsetTimout返回的一个数字标记值。

1.3.清除setTimeout的数字标记值

基本语法:

clearTimeout(setTimout的标记值)

//举例:
// 1. 创建延迟器,使用timeId保存延迟器的标记值
let timeId = setTimeout(()=>{
  console.log('我被执行了')
} , 3000)

// 2. 清除延迟器的继续执行
clearTimeout(timeId)

**说明:**其中的setTimeout,clearTiemout是一个全局函数,可以直接进行使用。

2. setinterval的场景

image.png 设置一个定时器,根据设置的时间间隔来执行指定的函数并且执行多次。

2.1 定义setInterval的基本语法

// setInterval会返回一个数字,表示当前定时器的标记值
let 变量 = setInterval(需要运行的函数,定时器执行间隔单位毫秒)

//举例:
let timeId = setInterval(()=>{
  console.log('我被执行了') // ✨✨✨每隔1秒执行一次
} ,
1000) // ✨✨每隔1秒执行一次 , 1秒 = 1000毫秒

说明:setInterval也会返回一个数字,表示当前定时器的标记值。它跟setTimeout不一样的是它可以执行多次。

2.2. 清除setInterval的执行

语法:

clearInterval(setInterval的标记值)

//举例:
// 1. 创建定时器,使用timeId保存延迟器的标记值
let timeId = setTInterval(()=>{
  console.log('我被执行了')
} , 3000)

// 2. 清除定时器器的继续执行
clearInterval(timeId)

说明:在实际编码中,我们并不会创建定时器然后马上进行清除,而是在特定的时机进行消除定时器。

3.案例-获取验证码

需求:

  1. 获取验证码(setTimout的使用练习)
  • 点击【发送验证码】按钮之后,延迟 2 秒(setTimeout)获取一个 4 位的随机数(Math.floor(1000+Math.random()*9000)),通过弹框显示出来(AlertDialog.show({message:}))
  1. 倒计时效果(setInterval的使用练习)
  • 点击【发送验证码】后 -> 文字变开始每隔1秒钟切换显示【xx秒后获取】 ,倒计时达到0秒的时候,恢复显示未【发送验证码】文字,并清除定时器
    • 关键技术:setInterval
    • 清除定时器使用: clearInterval

参考代码:

/*
 * 分析:
 * 点击发送验证码要做的事情:
 * 1. 在2秒钟之后随机生成一个4位数的数字,提示在界面上 (setTimout)
 *  -> 在 【发送验证码】的onClick事件中编写setTimout(()=>{
 *      4位数随机数生成 -> 1000 - 9999  Math.floor(Math.random() * 9000)) + 1000
 *      提示->alertDialog.show({message:四位随机数.toString()})
 *
 * },2000)
 *
 * 2. 进入60秒倒计时 (setInterval)
 *   -> 使用一个状态变量来控制秒数变化 @State time:number  = 0
 *   -> 点击【发送验证码】的时候,time  = 60
 *   -> 开启定时器setInterval,每隔1秒钟将time变量的值减1
 *   -> 其他处理:当time的值<=0的时候,清除定时器(clearInterval)
 * */

@Entry
@Component
struct LoginDemo {
  @State time: number = 0 //控制倒计时的状态变量
  timeId?: number // 用来存储定时器的标记

  build() {
    Column() {
      this.titleBuilder()
      TextInput({ placeholder: '请输入手机号' })
        .textInputExtend()
      Divider()
      Row() {
        TextInput({ placeholder: '请输入验证码' })
          .textInputExtend()
          .layoutWeight(1)
        Text(this.time == 0 ? '发送验证码' : `${this.time}秒后获取`)
          .fontSize(14)
          .fontColor(Color.Gray)
          .onClick(() => {
            // 如果this.time>0就表示定时器正在工作中,应该组织当前事件中的代码继续运行,以防止用户再次点击造成bug
            if (this.time > 0) {
              return  //阻止当前函数体中的当前代码之下的其他代码继续有哪些
            }

            // 1. 2秒以后提示一个4位数的验证码
            setTimeout(() => {
              //   1.生成4位数字
              let vcode = Math.floor(Math.random() * 9000) + 1000

              //   2. 提示给用户
              AlertDialog.show({ message: vcode.toString() })
            }, 2000)

            //   2. 修改状态变量time的值为60
            this.time = 60
            //   3. 开启定时器修改time的值
            this.timeId = setInterval(() => {
              this.time--

              //   3.1 time的值如果<=0 清除定时器
              if (this.time <= 0) {
                clearInterval(this.timeId)
              }
            }, 1000)
          })
      }
      .width('100%')

      Divider()

      Button('登录')
        .width('100%')
        .type(ButtonType.Normal)
        .backgroundColor('#ea6051')
        .margin({ top: 50 })

    }
    .padding({ top: 80, left: 40, right: 40 })
    .width('100%')
    .alignItems(HorizontalAlign.Start)
  }

  @Builder
  titleBuilder() {
    Text('短信登录')
      .fontSize(25)
      .fontWeight(600)
      .margin({ bottom: 30 })
  }
}

@Extend(TextInput)
function textInputExtend() {
  .backgroundColor(Color.White)
  .padding({ left: 0, top: 20, bottom: 20 })
  .placeholderColor('#ccc')
}