本篇主要内容:异步、定时器引发的思考

预计阅读时间:8分钟

了解

我们都知道在js中定时器有两种 
setInterval()
 、
setTimeout()
 
setInterval()
:按照指定的周期(以毫秒计)来调用函数或计算表达式。方法会不停地调用函数,直到 
clearInterval()
 被调用或窗口被关闭。 
setTimeout()
:在指定的毫秒数后调用函数或计算表达式。 
那么问题来了,定时器真的是定时执行的吗? 刚开始我认为定时器肯定是定时执行的啊,要不然怎么会叫做定时器呢,后来我感觉我好像错了,所以今天就来说说这个问题 定时器真的是定时执行的吗


测试

 var start = Date.now()
console.log('启动定时器前...')
setTimeout(function () {
console.log('定时器执行了: ', Date.now()-start)
}, 100)
console.log('启动定时器后...');

我们会发现定时器执行了101ms, 一般会延迟一丁点(可以接受),说白了就是准确的,如果说300ms之后执行呢?

var start = Date.now()
console.log('启动定时器前...')
setTimeout(function () {
console.log('定时器执行了: ', Date.now()-start)
}, 100)
console.log('启动定时器后...');
for (var i = 0; i < 1000000000; i++) { }

如果像上边这种情况,本来是200ms,但是现在变成了1941ms,那还合适吗? 
也就是说我们的定时器真的能保证定时吗? 
答案是不能,也可能延迟执行,是在原有设定的时间上又有延迟,加入本来是200ms, 那么现在是1941ms,所以说定时器并不能真正保证定时执行

注意:定时器的回调函数是在主线程执行,无论是非回调函数还是回调函数都是在主线程执行


JS执行方式

这时候就说到了一个概念 --- js是单线程执行的 
那如何证明js执行是单线程的呢?尤其是一些回调函数中,我们把握不住是主线程执行还是分线程执行的,所以我们现在就验证下js是单线程执行的

setTimeout(function () {
console.log('timeout 2')
}, 2000) setTimeout(function () {
console.log('timeout 1')
}, 1000)
function fn () {
console.log('fn()');
}
fn()
console.log('alert之前')
alert('提示...')
console.log('alert之后')

执行流程:fn() alert之前 弹窗

当我点击确认后, 
timeout 2
 和 
timeout 1
 是立即执行还是过一会执行

alert之后 timeout 1 timeout 2

我们发现是过一会执行,所以说 
alert()
的作用是暂停当前主线程,同时暂停计时。 点击确认后,回复程序执行和计时

小结 
如何证明js执行是单线程的? 
setTimeout()  的回调函数是在主线程执行的 
定时器回调函数只有在运行栈中的代码全部执行完后才有可能执行

setTimeout(function () {
alert('2222222')
console.log('timeout 2')
}, 2000) setTimeout(function () {
alert('1111111')
console.log('timeout 1')
}, 1000)
function fn () { console.log('fn()');
}
fn()
console.log('alert之前')
alert('提示...')
console.log('alert之后')

其实呢到现在咱们也不能清楚地看到JS是如何执行的,要说到这个,我们就得说下代码分类,之前也写过代码分类,全局代码和函数局部代码。

代码分类

这一次呢我们分为初始化代码和回调代码 
回调代码就是回调函数中的代码

setTimeout
 是本文的初始代码

接下来就是比较重要的一段函数了

setTimeout(function () {
console.log('timeout 0')
}, 0)
console.log('昼猫')

这一段代码中是谁先执行?

总结

JS引擎执行代码的基本流程: 
先执行初始化代码:包含一些特别的代码,例如:设置定时器、绑定事件监听、发送ajax请求 
在后面在某个时刻才会执行回调代码 
回调函数我们平常时候会说是异步执行 
也就是说某些代码(某些东西)必须在所有的初始化代码执行后才有可能得到被执行,这样的代码我们成为异步代码

 孔子东游记               公众号:昼猫笔记

文章转载公众号昼猫笔记

昼猫笔记 JavaScript -- 异步执行 | 定时器真的定时执行?的更多相关文章

  1. 昼猫笔记 JavaScript -- 作用域技巧!!

    简单理解 var zm = function (x) { var code = 'bb' return code }; 学过js的老哥们都知道,当这样简单的一个函数进入浏览器,浏览器开始解释代码,会将 ...

  2. 昼猫笔记 JavaScript -- 面向对象(I)

    本文内容搬运自公众号 原文链接 本文主要内容:面向对象 预计阅读时间:6分钟 面向对象的方式 单例模式(字面量定义) var obj = {} 类的实例 var obj = new Object() ...

  3. 昼猫笔记 JavaScript -- 闭包

      本次主要内容是 闭包 阅读时间: 约 3分钟 记得点个赞支持支持我哦 初步了解 先看下代码,输出结果是多少? function fn1 () { var a = 2 function fn2 () ...

  4. 昼猫笔记 从此告别复杂代码--JavaScript

    昼猫笔记--给你带来不一样的笔记 不止是笔记 更多的是思考 大家好,我是一只来自喵星的前端初学者,由于我们喵星人科技较为落后,昼猫从今天开始带着使命来到地球学习前端知识. 从今天开始,猫猫我就从Jav ...

  5. 昼猫笔记 -- 面向对象(II) - 继承

    继承 由于js不像java那样是真正面向对象的语言,js是基于对象的,它没有类的概念. 所以,要想实现继承,可以用js的原型prototype机制或者用apply和call方法去实现,还有就是js可以 ...

  6. 昼猫笔记--什么是DOM

    昼猫笔记--给你带来不一样的笔记 不止是笔记 更多的是思考 Hello,大家好,昼猫,今天来加深下DOM 什么DOM呢?它的全称叫 Document Object Model 通过全称可以知道它是 文 ...

  7. Spring定时器,定时执行(quartz)

    这个定时器与继承了timertask的定时器不同的是,这个定时器是更强大的,可以指定每分的第n秒,每天的第n时,每周的.每年的.来定时运行这个定时器.那么下面来讲诉如何使用quartz定时器. spr ...

  8. [转]oracle job有定时执行的功能,可以在指定的时间点或每天的某个时间点自行执行任务。

    oracle job有定时执行的功能,可以在指定的时间点或每天的某个时间点自行执行任务. 一.查询系统中的job,可以查询视图 --相关视图 select * from dba_jobs; selec ...

  9. ORACLE 定时执行存储过程

    推荐用dbms_scheduler方式更好 (2012-11-19注) /* 查询: select job,broken,what,interval,t.* from user_jobs t; job ...

随机推荐

  1. 访问Storm ui界面,出现org.apache.storm.utils.NimbusLeaderNotFoundException: Could not find leader nimbus from seed hosts ["master"]. Did you specify a valid list of nimbus hosts for confi的问题解决(图文详解)

    不多说,直接上干货! 前期博客 apache-storm-0.9.6.tar.gz的集群搭建(3节点)(图文详解) apache-storm-1.0.2.tar.gz的集群搭建(3节点)(图文详解)( ...

  2. c#学习0217

    1 继承 继承 1 子类是否继承了父类的构造函数 答案:子类并没有继承父类的构造函数 但是子类或默认调用父类的无参数的构造函数 在子类中创建父类对象 这样子类才可以使用父类的成员 如果在父类中声明了有 ...

  3. sftp权限

    用户: t1 t2 根目录: /home/data/ /home/data/t1/ drwxr-xr-x. 2 t1 t1 4096 Mar 24 17:26 t1 /home/data/t2/ dr ...

  4. swift语言点评十九-类型转化与检查

    1.oc比较: -(BOOL) isKindOfClass: classObj判断是否是这个类或者这个类的子类的实例 -(BOOL) isMemberOfClass: classObj 判断是否是这个 ...

  5. canvas处理图片

    canvas绘制图片的三种方法: drawImage(image, x, y) drawImage(image, x, y, width, height) drawImage(image, sourc ...

  6. Mac 如何修改Mac系统的默认截图路径

    step 1 :打在桌面或者其他任意位置创建一个文件夹:截图图库.我创建的路径是:/Users/yilin/Documents/截图图库(仅供参考) step 2:打开终端,输入以下命令:defaul ...

  7. LCT复习

    LCT,虚实链剖分.支持连边和断边操作.Tarjan制造. [HNOI2010]弹飞绵羊 当然这题分块可以做,常数小,但是LCT更无脑. 建立一个虚拟的弹飞节点\(n+1\),初始化时对于一个点假如再 ...

  8. [APIO2016]Gap

    题目:UOJ#206. 题目大意:由于过于冗长,不好解释,所以详见原题. 解题思路:这是一道交互题. 对于第一问,很容易解决.由于数列严格递增,所以不会出现相等的情况. 首先调用MinMax(0,10 ...

  9. UNIX系统高级编程——第五章-标准I/O库-总结

    基础: 标准I/O库在ANSI C中定义,可移植在不同的系统 文件指针(FILE):标准I/O库操作的不是文件描述符,而是流.FILE文件指针包含的是维护流所需的信息 通过函数fileno获取流的文件 ...

  10. nginx.conf.default

    [root@web03 conf]# vim nginx.conf.default #user nobody;worker_processes 1; #error_log logs/error.log ...