美文网首页
setTimeout 与 setInterval —— 实现优雅

setTimeout 与 setInterval —— 实现优雅

作者: YanaDH | 来源:发表于2022-10-27 17:27 被阅读0次

    1 定义与用法

    1.1 setTimeout

    1.1.1 定义

    在指定的毫秒数后调用函数或计算表达式

    1.1.2 用法

    setTimeout(code/function, milliseconds, param1, param2, ...)
    

    1.1.3 技术细节

    • code/function :必需,要调用一个代码串,也可以是一个函数
    • milliseconds :可选,执行或调用 code/function 需要等待的时间,以毫秒计。默认为 0 ,最短为4ms
    • param1, param2 :可选,传给执行函数的其他参数
    • 返回值 :返回一个 ID(数字),可以将这个ID传递给 clearTimeout() 来取消执行
    const fun = (param1, param2) => {
      console.log(param1, param2);
    }
    setTimeout(fun)
    setTimeout(fun, 1000, 'param1', 'param2')
    

    1.2 setInterval

    1.2.1 定义

    按照指定的周期(以毫秒计)来调用函数或计算表达式

    1.2.2 用法

    setInterval(code/function, milliseconds, param1, param2, ...)
    

    1.2.3 技术细节

    • code/function :必需,要调用一个代码串,也可以是一个函数
    • milliseconds :必需,周期性调用 code/function 之间的时间间隔,以毫秒计,最短为10ms
    • param1, param2 :可选,传给执行函数的其他参数
    • 返回值 :返回一个 ID(数字),可以将这个ID传递给 clearInterval() 来取消执行
    const fun = (param1, param2) => {
      console.log(param1, param2);
    }
    // setInterval(fun) //milliseconds 参数必须,否则疯狂执行代码块
    setInterval(fun, 1000, 'param1', 'param2')
    

    2 setInterval缺陷

    2.1 无视代码错误

    即使调用的代码报错了, setInterval 还是会周期性调用代码块

    let count = 1
    setInterval(() => {
        count++
        console.log(count);
        if(count > 3) throw new Error('setInterval 报错')
    }, 1000)
    

    改用 setTimeout

    let count = 0
    const fun = () =>{
      setTimeout(() => {
        count++
        console.log(count);
        if(count > 3) throw new Error('setTimeout 报错')
        fun()
      }, 1000);
    }
    fun()
    

    2.2 无视网络延迟

    在使用 Ajax 轮询服务器是否有新数据时,如果网络状态不佳,一个接口下发后还没有返回结果,此时 setInterval 还是会周期性调用代码块,导致客户端网络队列塞满 Ajax 请求

    const http = () => {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve()
        }, 3000);
      })
    }
    setInterval(async () => {
        await http()
        console.log('setInterval');
    }, 1000)
    

    改用 setTimeout

    const http = () => {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve()
        }, 3000);
      })
    }
    const fun = () =>{
      setTimeout(async () => {
        await http();
        console.log('setTimeout');
        fun()
      }, 1000);
    }
    fun()
    

    2.3 不保证间隔执行

    setInterval 周期性添加执行器到任务队列,如果调用的代码执行的时间大于设置时间间隔,它会跳过调用,这就导致漏执行

    3 优雅轮询

    递归调用 setTimeout() ,不需要后调用 clearTimeout() 清除定时器

    let timer = null
    const interval = () => {
      timer = setTimeout(() => {
        // 执行代码块
        interval()
      }, 1000)
    }
    interval()
    // 清除
    setTimeout(() => {
      clearTimeout(timer)
    }, 5000);
    

    相关文章

      网友评论

          本文标题:setTimeout 与 setInterval —— 实现优雅

          本文链接:https://www.haomeiwen.com/subject/rmjftdtx.html