zoukankan      html  css  js  c++  java
  • setTimeout和setInterval不容易注意到的一些细节

    今天没事翻了翻JS高程,看到了setTimeout部分有这么一句话:调用setTimeout()之后,该方法会返回一个数值ID,表示超时调用。这个超时调用ID是计划执行代码的唯一标识符,可以通过它来取消超时调用。

    然后我从书中上下左右找了半天也没发现有说这个ID的地方,于是乎抱着钻牛角尖的心态我去试了试,发现了一些很有意思的东西。

    var id1 =setTimeout(function(){},10);
    var id2 =setTimeout(function(){},10);
    console.log(id1); //1
    console.log(id2); //2
    这个不是重点,重点是我又试了一下setInterval():
    var id3 =setInterval(function(){},10);
    console.log(id3); //3
    也就是说这两个函数的id值是顺次创建的,一般情况下我们想要清除一个setTimeout()需要这么做:
    clearTimeout(id1);
    于是我想既然我们知道了它的id值是不是可以直接去清除呢?我就试了一下:
    clearTimeout(1);
    OK,成功了,完全没有问题!接着我又想既然他俩的id值都是数字能不能混着清除?然后又试了一下:
    clearTimeout(id3);
    还是成功了!这俩居然能够混用,我也是醉了。好吧,这个真是神奇,有必要记下来。

    接下来再说说这setTImeout()别的方面的一些特点吧。

    setTimeout()这个函数的第二个值是一个毫秒数,不能设置成0,或者说设置成0也没啥用,因为H5里面规定了它的最小值是4,也就是说小于4的人家会给你自动加上。

    假设可以是0的话下面这个结果也永远是1,3,2:
    console.log(1);
    setTimeout(function(){console.log(2)},0);
    console.log(3);
    为什么呢?这就要说到JS语言的特性上了,JS这门语言创作的目的就是为了高效、简单、快捷,所以创作初始就将它定成了一门单线程的语言,但是如果真是单线程的话又会出现很多的问题,比如说事件堵塞,每一个任务执行完了才能去执行下一个任务。打个比方:你朋友中午要来你家吃饭,你决定要给他做几个菜,其中有一道糖醋鱼,会做饭的人都知道做鱼要提前把鱼用调料腌上半天鱼肉才能入味,你早上把鱼腌上了,然后你就在旁边等这个鱼腌好,等了一上午鱼终于腌好了你才发现没有买别的菜,朋友这时候来你家做客你一道菜也没有做好,尴尬了。这就类似于一个单线程的任务,一个执行完了才能执行另一个,其中有大量的等待时间,造成了资源的浪费和任务的堵塞。JS为了解决这个问题引入了异步处理的方法,也就是说你腌了鱼直接扔一边接着去干别的事情,等别的事情弄好了再回来看看鱼腌好没。

    Web Work中规定了JS可以拥有多线程,但是同一时间只能拥有一个主线程,除了主线程其他线程不允许任何的dom操作,也就是说其他的线程类似于辅助线程。主线程中有一个执行栈,栈中的任务如果是同步执行结束了就会释放掉,如果是异步则会执行后进入辅助线程的任务队列之中,执行栈中如果空了主线程就会重新查找任务队列中的任务来执行,这叫做任务轮询。而今天我们的主角setTimeout也是一个异步的操作,而且比较不受待见,只有执行栈和任务队列中的任务全部执行完了才会去执行它,也就是说后面这个时间就是一个虚的数字,并不是真正意义上的执行后延时,因此即使它是0,也会是最后执行。

    吐槽一句写博客真是挺累的,打了没多久手都酸了,还是敲代码来的省事。最后再说说setTimeout这个函数的另一个用法吧,就是设定计时器:
    //计时器
    var num = 0;
    var max = 10;
    function setTime()
    {
    num++;
    console.log(num);
    if(num<max){
    setTimeout(setTime,1000);
    }else{
    console.log("Done");
    }
    }
    setTime();
    因为setInterval会一直循环如果忘了清除的话有可能会给用户带来不小的困扰,因此做一个计时器来有限次的执行是有很有必要的,当然,setInterval也并不是一无是处,比如常见的轮播图就离不开它,好吧其实setTimeout也能实现它,本来想夸两句的结果又把它黑了。
  • 相关阅读:
    AsyncTask Note
    从今以后我要写我写过的技术及代码
    金额阿拉伯数转中文
    [导入]匿名方法引起的异常
    [导入]对.net事件的看法
    [导入]把DataGrid控件定制成漂亮的课程表
    [导入]IIs上的证书安装要点
    oracle创建表空间
    如何在命令行更改IP地址
    server.mappath 与page命名空间说明
  • 原文地址:https://www.cnblogs.com/bing0117/p/5839577.html
Copyright © 2011-2022 走看看