当前位置: 首页 > 新闻动态 > 猜您喜欢 >

大前端终结者

作者:深圳纯量网络 阅读: 发布时间:2024-08-13 06:01

摘要:最近在开发小程序中,经常用到setTimeout和setInterval函数,曾经经常搞混这两个函数的使用,特意研究了一下这里做下总结,希望同行...

_wwe10大最痛终结技_大舰巨炮时代的终结

最近在开发小程序中,经常用到setTimeout和setInterval函数,曾经经常搞混这两个函数的使用,特意研究了一下这里做下总结,希望同行看了能有所收获,不再迷路。

首先,要说明的是setTimeout和setInterval是两个实现了定时调用的函数,而不是类似thread的线程。线程一般会在一个时间片内, 可以并发的执行调用,但这两个函数并不是这样使用的,因为我们都知道JavaScript都是以单线程的方式运行于浏览器的JavaScript引擎中的。

setTimeout和setInterval的作用只是把你要执行的代码在你设定的一个时间点插入JavaScript引擎维护的一个代码队列中, 插入代码队列并不意味着你的代码就会立马执行的,理解这一点很重要。

一、setTimeout

setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()。

funcName:function() {
  // dosomething1
    setTimeout(() => {
      // dosomething2
    }, 500);
  // dosomething3
}

以上代码的执行顺序是:先执行dosomething1的内容, 然后运行到setTimeout的地方, setTimeout会告诉浏览器说: "500ms后会插一段要执行的代码给你的队列中", 浏览器答应了(注意插入代码并不意味着立马执行), setTimeout代码运行后, 紧跟其后的dosomething3代码开始执行。

问题来了,如果dosomething3的代码执行时间超过500ms, 那结果会是如何? 500ms一到, dosomething2代码会立马执行吗?事实可能会让你有点失望, 在dosomething3执行过程中(执行了500ms后)dosomething2代码被插入代码队列, 但一直要等funcName的方法执行结束, 才会执行dosomething2代码段, 从代码队列上看dosomething2代码是在funcName后面的, 再加上js以单线程方式执行, 所以就很容易理解了。 如果是另一种情况, dosomething3代码执行的时间

用完定时器之后,要记得清除:clearTimeout(timeoutId) 这里的timeoutId是setTimeout返回的一个正整数编号,是定时器的唯一标识符。

wwe10大最痛终结技_大舰巨炮时代的终结_

二、setInterval

setInterval可以当成setTimeout的升级版,就像setTimeout循环调用自身,用法也跟setTimeout一样,用完时也要记得用clearInterval清掉定时器。

这里可能会存在两个问题:

1.时间间隔或许会跳过

2.时间间隔可能小于定时调用的代码的执行时间

click:function() {
  // dosomething1
    setInterval(() => {
      // dosomething2
    }, 500);
  // dosomething3
}

同样当funcName开始执行时,当dosomething1代码执行完后执行setInterval, 以此为一个时间点, 在200ms后插入dosomething2代码, funcName代码顺利结束, dosomething2代码开始执行, 如果dosomething2代码也执行了一个比较长的时间, 超过了接下来一个插入时间点400ms, 这样代码队列后又插入了一份dosomething2代码, dosomething2继续执行着, 而且超过了600ms这个插入时间点, 然后问题就来了, 开始以为代码队列后面会继续插入一份dosomething2代码...而实际情况是,由于代码队列中已经有了一份未执行的dosomething2代码, 所以600ms这个插入时间点将会被"无情"的跳过, 因为JavaScript引擎只允许有一份未执行的dosomething2代码,惊不惊喜意不意外?

所以有一种更好的方式来实现此功能,主要思路是递归:

setTimeout(() => {
  //processing 
  setTimeout(arguments.callee, interval); 
}, interval);

这里有个知识点:

arguments 的主要用途是保存函数参数, 有个callee属性,返回正被执行的Function对象,也就是所指定的Function对象的正文,这有利于匿名函数的递归或者保证函数的封装性。

但是现在已经不推荐使用arguments.callee();

因为访问 arguments 是个很昂贵的操作,因为它是个很大的对象,每次递归调用时都需要重新创建,影响现代浏览器的性能,还会影响闭包。

三、setTimeout和setInterval区别

setInterval在执行完一次代码之后,经过了给定的时间间隔,它还会自动重复执行代码,而setTimeout只执行一次那段代码。

setInterval和setTimeout都返回定时器对象标识符,用于clearInterval和clearTimeout调用

clearTimeout(showTimes) //清除已设置的setTimeout对象
clearInterval(showTimes) //清除已设置的setInterval对象

现在是不是觉得很简单,很容易区分?那么下面两个例子就很容易区分差别了。

例一:

setTimeout(function(){
  console.log("小马");
  setTimeout(function(){arguments.callee;},1000);
},1000)

例二:

setInterval(function(){
  console.log("小马");
},1000);

  • 原标题:大前端终结者

  • 本文由深圳纯量网络小编,整理排版发布,转载请注明出处。部分文章图片来源于网络,如有侵权,请与纯量网络联系删除。
  • 微信二维码

    CLWL6868

    长按复制微信号,添加好友

    微信联系

    在线咨询

    点击这里给我发消息QQ客服专员

    点击这里给我发消息电话客服专员

    在线咨询

    免费通话


    24h咨询☎️:132-5572-7217


    🔺🔺 24小时客服热线电话 🔺🔺

    免费通话
    返回顶部