发表过一片博客《跟着我用JavaScript写计时器》,比较基础.....有网友说应该写一下setTimeout的原理和机制,嗯,今天就来写一下吧:

直奔主题:setTimeout和setInterval是如何工作的呢?

我们知道,js是单线程执行的(单线程j就是说在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行)。所以其实setTimeout和setInterval所谓的“异步调用”事实上是通过将代码段插入到代码的执行队列中实现的。

而如何计算插入的时间点呢?自然是要用到我们所说的timer,也就是计时器。当执行setTimeout和setInterval的时候,timer会根据你设定的时间“准确”地找到代码的插入点。当队列“正常”地执行到插入点时,就触发timer callback,也就是我们设定的回调函数:


function fn() {
/*
here is some codes
*/ alert("javascript");
setTimeout(function() {alert('ok!')},1000);
}
onload=fn;

上面这个例子就是我们通常的用法,应该容易理解。可是,timer真的能那么准确么?代码队列的执行真的能那么正常么?

还记得吗?重新认识所谓的“异步”

刚刚已经知道,事实上setTimeout和setInterval只是简简单单地通过插入代码到代码队列来实现代码的延迟执行(或者说异步执行)。但是事实上所谓的异步只是一个假象——它同样运行在一个线程上! 始终是单线程!

那么问题就来了,要是在代码插入点前的代码执行时间超过了传入setTimeout或setInterval的设定时间会怎样呢?让我们来看看这段代码:


function fn() {
setTimeout(function(){alert('can you see me?');},1000);
while(true) {}
}

你觉得这段代码的执行结果是什么呢?答案是,alert永远不会出现。



这是为什么呢?因为,while这段代码没有执行完(如图,浏览器一直在解析while的代码),所以插入在后面的代码便永远不会执行。

综上所述,其实JS终归是单线程产物。无论如何“异步”都不可能突破单线程这个障碍。所以许多的“异步调用”(包括Ajax)事实上也只是“伪异步”而已。只要理解了这么一个概念,也许理解setTimeout和setInterval也就不难了。

JavaScript的setTimeout和setInterval的深入理解的更多相关文章

  1. setTimeout和setInterval的深入理解

    以前写的setTimeout和setInterval的文章有些不足之处,今天抽时间整理了一下,要想真正理解还得从javascript的单线程机制说起 大概半年前发表过一篇关于setTimeout和se ...

  2. Javascript的setTimeOut()和setInterval()的定时器用法

    Javascript用来处理延时和定时任务的setTimeOut和setInterval函数应用非常广泛,它们都用来处理延时和定时任务,比如打开网页一段时间后弹出一个登录框,页面每隔一段时间发送异步请 ...

  3. Javascript中setTimeout和setInterval的区别和使用

    在javascript中,window对象有两个主要的定时方法,分别是setTimeout 和 setInterval,其语法基本上相同,但是完成的功能取有区别. setTimeout方法是定时程序, ...

  4. JavaScript的setTimeout()和setInterval()

    1. setTimeout()方法 作用:在制定的毫秒数后调用函数或计算表达式 语法: setTimeout(code,millisec) 实例: function timedMsg() { var ...

  5. JavaScript 关于setTimeout与setInterval的小研究

    说明 在开发功能"轨迹播放"时,遇到了一个情况. 原先同事已经开发了一版,这次有个新功能:点击线上任意一点后可以从点击处重新播放. 看了一下原来的版本,发现同时使用了setTime ...

  6. JavaScript中setTimeout()和setInterval()的区别

    含义: setTimeout()和setInterval()经常被用来处理延时和定时任务.使用setTimeout()处理延时任务,而使用setInterval()方法处理定时任务: setTimeo ...

  7. JavaScript———从setTimeout与setInterval到AJAX异步

    setTimeout与setInterval执行 首先我们看一下以下代码打印结果 console.log(1); setTimeout(function() { console.log(2); },1 ...

  8. javascript使用setTimeout、setInterval时找不到变量的问题

    我们在某个作用域内或者在自己定义的一个类里调用setTimeout.setInterval会经常会遇到找不到某个变量的错误. 比如下面这个例子: window.onload = function(){ ...

  9. javascript的setTimeout以及setInterval休眠问题。

    前端码农们在做项目中时候,必定不可少的需要做到轮播效果.但是有些特殊的需求,比如: 需要做到第一个容器内容轮播滚动之后,第二个容器内部再轮播滚动,再第三个容器内容轮播滚动. 这时候我的一开始的思路是: ...

随机推荐

  1. IBatisNet:让insert操作返回新增记录的主键值

    项目引用ibatis包: IBatisNet.Common.dll --文件版本1.6.2.0 IBatisNet.DataAccess.dll IBatisNet.DataMapper.dll 项目 ...

  2. NodeJS系列~第四个小例子,NodeJs处理Get请求和Post请求

    返回目录 说在前 对于HTTP请求来说,我们通常使用的是Get和Post,除此之外还有put,delete等,而对于get来说,比较lightweight,只是对字符串的传输,它会被添加到URL地址里 ...

  3. Java线程:线程状态的转换

    Java线程:线程状态的转换   一.线程状态   线程的状态转换是线程控制的基础.线程状态总的可分为五大状态:分别是生.死.可运行.运行.等待/阻塞.用一个图来描述如下:   1.新状态:线程对象已 ...

  4. [Spring框架]Spring IOC的原理及详解。

    这里感谢 CSDN 的原博客:http://blog.csdn.net/m13666368773/article/details/7802126 看后  受益匪浅,这里再重温一遍Spring IOC ...

  5. Atitit 面向对象  封装的实现原理

    Atitit 面向对象  封装的实现原理 1.1. 动态对象的模拟使用map+函数接口可以实现1 1.2. 在用结构体 + 函数指针 模拟 对象 1 1.3. This指针..1 1.4. " ...

  6. NFC:Arduino、Android与PhoneGap近场通信

    NFC:Arduino.Android与PhoneGap近场通信(第一本全面讲解NFC应用开发的技术著作移动智能设备近距离通信编程实战入门) [美]Tom Igoe(汤姆.伊戈),Don Colema ...

  7. 使用 flow.ci 实现 Android 自动化测试与持续集成

    在上篇文章--如何实现 Android 应用的持续部署中,我们使用的是 flow.ci + Github + fir.im 实现 Android 应用的持续部署.对于 Android 开发者,他们可能 ...

  8. 转 - ubuntu apache2下目录结构

    ubuntu apache2下目录结构 原文:http://blog.csdn.net/jibcy/article/details/8060651 在Windows下,Apache的配置文件通常只有一 ...

  9. IOS开发之控件篇UICollectionViewControllor第一章 - 普通介绍

    1.介绍 UICollectionView和UICollectionViewControllor是IOS6.0后引入的新控件 使用UICollectionView必须实现三个接口: UICollect ...

  10. 理解与模拟一个简单web服务器

    先简单说下几个概念,根据自己的理解,不正确请见谅. web服务器 首先要知道什么是web服务器,简单说web服务器就是可以使用HTTP传输协议与客户端进行通信的服务器.最初的web服务器只能用来处理静 ...