【JS】执行机制解析,设置定时器、取消定时器

目录

JavaScript 执行机制

JavaScript 定时器

1、setTimeout()

2、setInterval() 

3、setImmediate()

4、requestAnimationFrame()

5、clearTimeout() 取消定时器

6、 clearInterval()取消定时器

6、使用setTimeout模拟setInterval行为

setInterval与setInterval的区别


JavaScript 执行机制

浏览器( JavaScript 引擎)执行 JavaScript 的机制是基于事件循环的。由于 JavaScript 是单线程,同一时间只能执行一个任务。为了避免某些长时间任务造成无意义等待,JavaScript 引入了异步概念。

同步任务直接在主线程队列中顺序执行,而异步任务会进入另一个任务队列,不会阻塞主线程。等到主线程队列空了(执行完了)的时候,就会去异步队列查询是否有可执行的异步任务了(异步任务通常进入异步队列之后还要等一些条件才能执行,如 ajax 请求文件读写),如果某个异步任务可以执行了便加入主线程队列,以此循环。

JavaScript 定时器

定时器也是一种异步任务,通常浏览器都有一个独立的定时器模块,定时器的延迟时间就由定时器模块来管理,当某个定时器到了可执行状态,就会被加入主线程队列。

另外,多个定时器如不及时清除clearTimeout()),会造成干扰,使延迟时间更加捉摸不透。所以,不管定时器有没有执行完,要及时清除不需要的定时器。

1、setTimeout()

设置一个定时器,在定时器到期后执行一次函数或代码段:setTimeout(fn, x) 表示延迟 x 毫秒之后执行 fn

var timeoutId = setTimeout(code, delay, param1, param2, ...)
var timeoutId = setTimeout(func, delay, param1, param2, ...)
  • timeoutId 定时器ID
  • func 延迟后执行的函数
  • code 延迟后执行的代码字符串,不推荐使用
  • delay 延迟的时间(单位:毫秒),默认值为0
  • param1,param2 向延迟函数传递而外的参数,IE9以上支持 
  1. HTML5 规范规定最小延迟时间不能小于 4ms ,即 x 如果小于 4 ,会被当做 4 来处理。 不过不同浏览器的实现不一样,比如,Chrome可以设置1ms,IE11/Edge是4ms。
  2. setTimeout() 方法不是 Ecmascript 规范定义的内容,而是属于BOM提供的功能。setTimeout() 延迟也是有上限的,如果大于 2  的 31 次方的话,会立即执行,延迟无效。

2、setInterval() 

以固定的时间间隔重复调用一个函数或者代码段:

var intervalId = window.setInterval(func, delay , param1, param2, ...]);
var intervalId = window.setInterval(code, delay);
  • intervalId 重复操作的ID
  • func  延迟调用的函数
  • code 代码段
  • delay 延迟时间,没有默认值

对于 setInterval(fn, 100) 容易产生的误区:并不是上一次 fn 执行完了之后再过 100ms 才开始执行下一次 fn。 事实上,setInterval 并不管上一次 fn 的执行结果,而是每隔 100ms 就将 fn 放入主线程队列,而两次 fn 之间具体间隔多久就不一定了,跟 setTimeout 实际延迟时间类似,和 JavaScript 执行情况有关。 

3、setImmediate()

浏览器完全结束当前运行的操作之后立即执行指定的函数(仅 IE10 和 Node 0.10+ 中有实现),类似setTimeout(func, 0) 

在IE11/Edge中,setImmediate()延迟可以在1ms以内,而setTimeout(0)有最低4ms的延迟,所以setImmediate()setTimeout(0)更早执行回调函数。

该方法可以用来替代setTimeout(0)方法来滞后完成一些需要占用大量cpu时间的操作

下面的JavaScript可以用来兼容那些不支持setImmediate方法的浏览器:

if (!window.setImmediate) {
  window.setImmediate = function(func, args){
    return window.setTimeout(func, 0, args);
  };
  window.clearImmediate = window.clearTimeout;
}

4、requestAnimationFrame()

专门为实现高性能的帧动画而设计的API,但是不能指定延迟时间,而是根据浏览器的刷新频率(帧)而定。

var requestId = window.requestAnimationFrame(func);

5、clearTimeout() 取消定时器

定义:阻止/取消 setTimeout() 方法设置的定时执行函数。

参数:id_of_settimeout是调用 setTimeout() 函数时所返回的ID值,使用该返回标识符作为参数,可以取消该 setTimeout() 所设定的定时执行操作。

注意: 要使用 clearTimeout(id_of_setinterval) 方法, 在创建执行定时操作时要使用全局变量:

var myVar = setTimeout(function(){ alert("Hello"); }, 3000);
clearTimeout(myVar);

6、 clearInterval()取消定时器

定义: 可取消/停止由 setInterval() 函数设定的定时执行操作。

参数:id_of_setinterval是调用 setInterval() 函数时所返回的 ID 值,只有使用该返回标识符作为参数,才可以取消该 setInterval() 所设定的定时执行操作。

注意: 要使用 clearInterval() 方法, 在创建执行定时操作时要使用全局变量:

var myVar = setInterval(function(){ myTimer() }, 1000);
clearInterval(myVar);

6、使用setTimeout模拟setInterval行为

通常情况下:递归的方式使用setTimeOut(),效果相当于使用setInterval()

好处:

  1. 简化代码
  2. 保证异步队列的函数调用顺序的精准度,setInterval的缺陷会导致数据量大的时候,异步队列的函数调用出现执行顺序的错乱。比如这个函数还没执行完又开始执行下一个,递归则不会,递归是当前函数执行完才在栈空间递归创建函数的下一个实体并调用。
//参数: 毫秒  需要执行的方法
function console1() {
    console.log(111);
    if(timer){
        clearTimeout(timer);
    }
    timer = setTimeout(function(){
        console1();
    }, 3000);
}
console1()

setIntervalsetInterval的区别

如果是setTimeoutsetInterval的话,它俩仅仅在执行次数上有区别,setTimeout一次、setInterval n次。

而通过setTimeout模拟的setIntervalsetInterval的区别则在于:setTimeout只有在回调完成之后才会去调用下一次定时器,而setInterval则不管回调函数的执行情况,当到达规定时间就会在事件队列中插入一个执行回调的事件

你可能感兴趣的:(javascript,javascript,前端,定时任务)