setTimeout&setInterval&任

2019-01-05  本文已影响7人  sweetBoy_9126

setTimeout

几秒后执行一次代码。
当我们运行setTimeout或者setInterval的时候会立刻拿到一个数值,这个数值就是它们本身的一个返回值,你可以认为是它们的id或者是编号。
我们可以通过它们每次的返回值编号来清除它们

setInterval

每隔几秒后执行一次代码

任务队列

js是单线程,也就是说同一个时间只能做一件事,这也就意味着所有任务需要排队,前一个任务结束,才会执行后一个任务

(1)所有同步任务都在主线程里的执行栈(stack)里排队执行
(2)主线程之外,还存在一个"任务队列"。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。

只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。

"任务队列"是一个先进先出的数据结构,排在前面的事件,优先被主线程读取。主线程的读取过程基本上是自动的,只要执行栈一清空,"任务队列"上第一位的事件就自动进入主线程。但是,由于存在"定时器",主线程首先要检查一下执行时间,某些事件只有到了规定的时间,才能返回主线程。

上图中,主线程运行的时候,产生堆(heap)和栈(stack),栈中的代码调用各种外部API,它们在"任务队列"中加入各种事件(click,load,done)。只要栈中的代码执行完毕,主线程就会去读取"任务队列",依次执行那些事件所对应的回调函数。

例题1:

var isOk = true
setTimeout(function(){
  isOk = false
})
while(isOk){
}
console.log(3)

上面的代码什么也不会输出
原因是,因为一开始代码运行先把同步任务按顺序放到stack中执行,也就是会先执行var isOk = true和while(isOk){}因为只有stack里的同步代码执行完了,才会去任务队列里处理异步,而isOk一直是true,一直没结束所以不会继续往下执行也不会去执行setTimeout里面的代码

例题2:

for(var i = 0;i<10;i++){
  setTimeout(function(){
    console.log(i)
  },1000)
}
//10个10

上面的代码最后会打印出10个10
例题解析:for循环是同步代码,会先放入stack里执行,每次循环都会创建一个定时器,for循环结束后i是10,开始执行异步setTimeout里的代码,因为有10个所以会打印出10个10

函数节流(使用方法要在监听事件里使用,比如input就是input事件里使用)
如果某一个函数在一定时间内连续执行了很多次,把前面的都忽略掉,我们以最后一次为准,也就是当你停下来的时候在一段时间后才会去执行,当你连续操作的时候就去不断的清除原来的计时器,新建新的计时器,然后去重新计时到指定时间才执行

var time
function fn(){
    if(time){
        clearTimeout(time)
    }
    time = setTimeout(()=>console.log('aaa'),3000)
}
fn()
fn()
fn()

改造

function throttle(fn, delay){
  var timer = null
  return function(){
    clearTimeout(timer)
    timer = setTimeout(function(){
      fn()
    },delay)
  }
}
function fn(){
  console.log('hell0')
}
var fn2 = throttle(fn, 1000)
fn2()
fn2()
``



上一篇 下一篇

猜你喜欢

热点阅读