理解JavaScript的单线程的理念对于JavaScript学习,以及掌握其中的一些设计机制非常重要,比如回调、定时器。对于后续学习NodeJS也有很大的帮助。

通过先demo,后总结的形式,使得JavaScript的单线程更易于明白。

  1. 1 var a = 1;  //全局变量a
  2. 2 function test(){
  3. 3     var a=2;  //test中变量a
  4. 4     setTimeout(function(){
  5. 5         alert(a); //输出test中变量a
  6. 6         a=3;  //修改test中变量a
  7. 7     },3000);
  8. 8     a=4; //修改test中变量a
  9. 9     setTimeout(function(){
  10. 10         alert(a); //输出test中变量a
  11. 11         a=5; //修改test中变量a
  12. 12    },1000);
  13. 13    alert(a); //输出test中变量a
  14. 14 }
  15. 15 test(); //执行test函数
  16. 16 alert(a); //输出全局变量a
  17. //运行结果:4 1 4 5
  18. /* 结果解析:先输出test()运行结果4,然后输出之后一行代码的1,然后1000ms之后输出test()中的变量a=4,最后3000ms之后输出test()中的变量a=5 */
  19. /*
  20. 运行机制:
  21. 1. JavaScript是单线程,从上往下依次执行
  22. 2. setTimeout异步方法存放在任务队列中,JS主线程执行完成之后,才会取任务队列中的任务到JS主线程中执行!
  23. -> 先执行15行,然后执行16行
  24. -> 执行15行,调用test()方法
  25. -> 调用test()方法,先创建一个a变量,然后将第一个setTimeout放到setTimeout对应的线程中执行(启动定时器timer),第8行,修改test中变量a为4,然后将第二个setTimeout添加到setTimeout对应的线程队列中执行,执行13行,输出test中变量a,此时为4;然后执行16行,输出全局变量a,此时为1.
  26. -> 1000ms之后,将第二个setTimeout的回调函数,添加到JS任务队列中,3000ms后将第一个setTimeout的回调函数,添加到JS任务队列中。
  27. -> JS主线程执行完成之后,会执行任务队列的事件,第二个setTimeout优先进入任务队列,所以优先执行,执行第10行,输出test中的变量a,值为4,然后di11行,将test中的变量a修改为5;2000ms之后第一个setTimeout进入任务队列,此时JS主线程栈为空,所以将其添加到JS主线程进行执行,第5行,输出test中的变量a,此时变量的值为5,第6行修改test变量a为3.
  28. */

由此延伸以下代码:

  1. var a = 1;
  2. var date = +new Date(); // 小技巧:通过"+"转换为整数
  3. function test(){
  4. var a=2;
  5. setTimeout(function(){
  6. console.log(a+'--'+ (new Date()-date));
  7. a=3;
  8. },3000);
  9. a=4;
  10. setTimeout(function(){
  11. console.log(a+'--'+ (new Date()-date));
  12. a=5;
  13. },1000);
  14. console.log(a+'--'+ (new Date()-date));
  15. }
  16. while(new Date-date <1000){
  17. }
  18. test();
  19. console.log(a+'--'+ (new Date()-date));
  20. //执行结果:4-1000 1-1001 4-2000 5-4001

结合以下博客,整理一些重要概念:

http://www.ruanyifeng.com/blog/2014/10/event-loop.html

http://www.cnblogs.com/Mainz/p/3552717.html

1、作为脚本语言,JavaScript主要功能是与用户互动,以及操作DOM。假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准? ->So: JavaScript就是单线程。

2、JavaScript的任务分成两种:同步任务和异步任务。同步任务:在主线程上排队执行的任务,只有上一个任务执行完成了,才会执行下一个任务。异步任务:不进入主线程,而进入“任务队列”的任务,只有“任务队列”通知主线程,某个任务队列可以执行了,等主线程执行完成,任务队列才会进入主线程执行。 -> So:只要主线程空了,就会去读“任务队列”,这就是JavaScript的运行机制。

3、主线程从“任务队列”中读取事件,这个过程是循环不断的,所以整个事件又叫“事件循环”(Event Loop)。

HTML5规定setTimeout()的第二个参数的最小值(最短间隔),不得低于4ms,如果低于4ms就会自动增加。在此之前,老版本浏览的都将最短时间设置为10ms。另外,对于那些DOM变动(尤其是设计页面重新渲染的部分),通常不会立即执行,而是每16ms执行一次。这是使用requestAnimationFrame()的效果要好于setTimeout()。

4、需要注意的是:setTimeout只是将事件插入“事件队列”,必须等到前面代码(执行栈)执行完,主线程才会去执行他指定的回调函数。如果当前代码耗时很长,有可能要等很久,所以并没有办法保证,回调函数一定会在setTimeout()指定的是时间执行。

Javascript是单线程,单线程就意味着所有任务需要排队。然后会将所有任务分成两类:同步任务和异步任务!同步任务:在主线程上执行的任务,只有前一个任务执行完成,才会执行后一个!异步任务:不进入主线程、而进入“任务队列”的任务。

Js是单线程的,但是浏览器是多线程的!浏览器是事件驱动的!

JS运行在浏览器中,是单线程的,每个window一个JS线程,但是浏览器不是单线程。可能有多个如下线程:

Javascript引擎线程、界面渲染线程、浏览器事件触发线程、Http请求线程。

setTimeout可以改变,js执行顺序。比如:我们想要输出Hello World,world必须在hello之后输出,不管我们代码的顺序怎么样都输出同样的效果,这个时候就可以借助setTimeout。

  1. //代码一
  2. var date =  +new Date();
  3. console.log('Hello',new Date()-date);
  4. setTimeout(function(){
  5. console.log('world',new Date()-date);
  6. },500);
  7. //代码二:
  8. var date =  +new Date();
  9. setTimeout(function(){
  10. console.log('World',new Date()-date);
  11. },500);
  12. console.log('Hello',new Date()-date);
  13. //以上两个代码运行结果一样,结果都是:先输出Hello ,然后500ms之后输出World![实际运行:501ms]

浏览器中定时器也是一个线程!

Javscript是单线程的,ajax请求确实是异步的!原因是ajax请求的时候,是在浏览器的Http请求线程中执行的,执行之后的回调函数会放到Javascript线程中执行!

Summary:

Javascript是单线程的,浏览器是多线程的,浏览器的线程包括:JS引擎线程、界面渲染线程、浏览器事件线程、Http请求线程。不过不同的浏览器提供的线程是有区别的。一般JS引擎线程和界面渲染线程是互斥的,两个线程不能同时执行,否则,就会出现界面渲染线程和JS线程修改同一个DOM样式的矛盾问题!

from: http://developer.51cto.com/art/201703/533796.htm

JavaScript单线程 setTimeout定时器相关推荐

  1. 前端开发技术-剖析JavaScript单线程

    JavaScript单线程和多线程是很多小白同学入门的时候问到最多的问题,虽然官方给出过解释但对于新手来说并不友好,今天小千就来给大家介绍一下JavaScript的单线程. 一. 浏览器的进程和线程 ...

  2. JavaScript单线程和浏览器事件循环简述

    JavaScript单线程 在上篇博客<Promise的前世今生和妙用技巧>的开篇中,我们曾简述了JavaScript的单线程机制和浏览器的事件模型.应很多网友的回复,在这篇文章中将继续展 ...

  3. 关于Javascript 中 setTimeout和setInterval的总结和思考

    1. JavaScript 单线程 我们通常说,javascript是单线程,指的是解释和执行js代码的引擎是单线程. 而对于浏览器来说,浏览器并不是单线程的,浏览器的线程通常包括:渲染引擎线程(负责 ...

  4. JavaScript中的定时器详解

    前言 JavaScript 中有两种定时器: setTimeout():指定时间后执行一段代码(延迟执行). setInterval():每隔一段时间执行一段代码(间隔执行). 下面单独对两种计时器进 ...

  5. javascript中setTimeout()函数

    javascript中setTimeout()函数 大家都知道javascript中的setTimeput()函数的作用,一般会用他来处理一些连续的事情,们先看一个例子: <head>   ...

  6. Javascript/Jquery——简单定时器

    第一种方法: <%@ page language="java" contentType="text/html; charset=UTF-8"pageEnc ...

  7. JavaScript学习05 定时器

    JavaScript学习05 定时器 定时器1 用以指定在一段特定的时间后执行某段程序. setTimeout(): 格式:[定时器对象名=] setTimeout("<表达式> ...

  8. javascript来实现定时器

    使用javascript来实现定时器 javascript中的setTimeout函数,用来实现定时器,第一个参数为实现的调用函数,第二个参数为定时的时间,单位为秒数.她点为该函数只可以调用一次 下面 ...

  9. JavaScript单线程运行机制与并发模型

    一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一时间只能做一件事.具体地,一个window对应一个JavaScript线程. JavaScript ...

最新文章

  1. 分享一个监控MFS的nagios插件
  2. MapInfo中常用查询函数及用法
  3. LeetCode Increasing Triplet Subsequence(动态规划)
  4. mysql 锁-比较详细、深入的介绍
  5. 《精益软件度量——实践者的观察与思考》—第1章1.1节精益软件开发的度量体系...
  6. 数字语音信号处理学习笔记——语音信号的短时时域分析(1)
  7. ES报错:Connection reset by peer 解决经历
  8. 2018安徽省计算机一级试题答案,2018年计算机等一级考试试题100题及参考答案.docx...
  9. 操作系统上机作业--根据莱布尼兹级数计算PI(2)(多线程)
  10. CentOs6.5安装使用数据恢复软件extundelete
  11. mysql 数据联合查询语句_MySQL - 数据查询 - 联合查询
  12. 软件工程专业要学什么课程?
  13. Android Studio实现用户登陆界面demo(xml实现)
  14. Vue移动端 手机六位数密码框
  15. 【Git/Bugfix系列】fatal: in unpopulated submodule的分析和解决方案
  16. pandas数据透视表
  17. Java微信小程序支付篇
  18. 学科实践活动感悟50字_初中学科实践活动记录50字3篇
  19. 移动端点击加qq好友和加入qq群
  20. xmodem java_Xmodem XMODEM协议是一种串口通信中广泛用到的异步文件传输协议 联合开发网 - pudn.com...

热门文章

  1. 搭建属于自己的wiki
  2. 机器学习算法加强——聚类
  3. 【风控场景】互利网上数字金融典型场景: 网络支付
  4. 移动金融业务风控框架及设备风险识别的意义(上)
  5. 盘点区块链的2018:技术与工具演进篇
  6. 机器学习入门系列二(关键词:多变量(非)线性回归,批处理,特征缩放,正规方程
  7. android webservices 返回多行多列数据,Pandas: 如何将一列中的文本拆分为多行?
  8. Redis - RedisTemplate及4种序列化方式深入解读
  9. Android获取相册中图片的路径 4.4版本前后的变化
  10. 学习笔记(一)——HTML学习