setTimeout和setInterval相关面试题

500 阅读1分钟

参考

zh.javascript.info/settimeout-… juejin.cn/post/684490…

setInterval

var intervalID = scope.setInterval(func, delay, [arg1, arg2, ...]);

  • func 要执行的函数
  • delay 延时
  • 【arg1,】 可选 当定时器过期的时候,将被传递给func指定函数的附加参数

setTimeout

var timeoutID = scope.setTimeout(function[, delay, arg1, arg2, ...]);

用setTimeout 实现一个setInterval

 function mySetInterval(callBack,delay){
    let timer = {}
    let timeId
    const fn = ( )=>{
        callBack()
        timer.timeId=  setTimeout(()=>{
            fn()
        },delay)
    }
    timer.timeId =  setTimeout(fn,delay)
    return obj
}

const timer = mySetInterval(function(){console.log('aaa')},2000)


setTimeout(() => {
    clearTimeout(timer.timeId)
}, 10000);

用timer.timeId 存储setTimout 是因为 如果用基本类型存储 返回的是一个值得拷贝,清除时不起作用

用setTimeout实现setInterval 和setTnterval 的区别

setInterval

image.png

setTimeout实现的setInterval

image.png

可以看到setTimeout实现的间隔是不变的,而setInterval的间隔包含函数本身执行的时间

轮询接口

五秒调用一次接口 直接使用上边实现的方法接口 当然 我们也可以简单实现一下

const timeid = setTimeout(function fn(){
    /**
    * 请求代码
    *
    */
    
    timeid = setTimeout(fn,delay)
},delay)

防抖节流

// 防抖 事件在n秒后执行
        function debounce(callBack,delay){
            let timer = null
            return  function(){
                const _this = this
                const arg = Array.prototype.slice.call(arguments)
                if(timer){
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                    callBack.apply(_this,arg)
                }, delay);
            }

        }

        // 节流 定时执行 用一个标识来判断
        function throttle(cb,delay){
            let state = true
            return function(){
                // 一定时间内不再执行
                if(!state){
                    return false
                }
                state = false
                 setTimeout(() => {
                    cb()
                    state= true
                }, delay);
            }
        }

宏任务

setTimeout 和 setInterval 都属于宏任务,都会执行完当前脚本再执行