setTimeout的原理及在JavaScript线程执行队列中的位置
来源:互联网 发布:app数据接口怎么写 编辑:程序博客网 时间:2024/04/30 03:40
setTimeout的原理及在JavaScript线程执行队列中的位置
开发中经常使用setTimeout进行一些延迟操作。昨天突然想了解下setTimeout的handler到底在队列中的什么位置特别好奇。今天特地来测试下。
定义和用法
setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。
语法
setTimeout(code,millisec)
提示和注释
提示:setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()。
以上定义来源于w3school.com
JavaScirpt线程
先了解下浏览器,浏览器是多线程的。
- JavaScript引擎线程
- 界面渲染线程
- 浏览器事件触发线程
- Http请求线程
JS运行在浏览器中,是单线程的,每个window一个JS引擎线程。既然是单线程的,的在某个特定的时刻只有特定代码能被执够行,并阻塞其它的代码。(至于ajax的实现这里就不说了。)
原理
来了解下setTimeout的简单的原理:
setTimeout调用的时候,JavaScript引擎会启动定时器timer,大约millisec(ms)以后执行code,当定时器时间到,就把该事件放到主事件队列等待处理。
注意:
浏览器JavaScript线程空闲的时候才会真正执行
为什么呢?因为当JavaScript线程的正在出来其他JavaScript代码时,其实以已经阻塞了其他的代码,其中包括的setTimeout的定时器部分的实现。
代码测试
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <script type="text/javascript"> function testHandler() { console.log("调用了setTimeout的函数"); } window.onload = function () { console.log("开始"); console.log("设置setTimeout 100ms"); setTimeout(testHandler,100); console.log("休眠1000ms"); sleep(1000); testNext(); console.log("结束"); } function testNext() { console.log("后续执行的函数"); } function sleep(number) { var now = new Date(); var exitTime = now.getTime() + number; while (true) { now = new Date(); if (now.getTime() > exitTime) return; } } </script></head><body></body></html>
最终浏览器输出的结果:
此处setTimeout其实只延迟了100ms。而进setTimeout到结束中先模拟休眠了2000ms,然后再执行了testNext函数。但是从测试结果来看实际上testHandler却是在整个队列的最后。这就解释了上诉中说的,setTimeout将code加入到队列的操作必须是在线程空闲的时候才会执行了。
millisec参数有什么用?
上诉测试发现,实际应用中。setTimeout的millisec参数不管你设置多少,实际执行都是在线程的最后,因为在执行一个操作的时候,JavaScript肯定是一直把代码执行完后再走setTimeout绑定的code的。
那么问题来了。setTimeout(handler,0)和setTimeout(handler,100)在单独使用时,好像并没有区别。(中间执行的代码处理时间超过100ms时)
<script type="text/javascript"> function testHandler() { console.log("调用了setTimeout的函数"); } window.onload = function () { console.log("开始"); console.log("设置setTimeout 100ms"); setTimeout(testHandler,100); setTimeout(function () { console.log("调用了setTimeout的函数2"); }, 50); console.log("休眠1000ms"); sleep(1000); testNext(); console.log("结束"); } function testNext() { console.log("后续执行的函数"); } function sleep(number) { var now = new Date(); var exitTime = now.getTime() + number; while (true) { now = new Date(); if (now.getTime() > exitTime) return; } } </script>
输出结果:
个人认为millisec一般在多个setTimeout一起使用的时,需要区分哪个先加入到队列的时候才有用,否则都可以设置成setTimeout(handler,0)(异步操作不在讨论范围内)
文章转载自:http://www.cnblogs.com/Jersen/p/4887225.html
- setTimeout的原理及在JavaScript线程执行队列中的位置
- Javascript引擎单线程机制及setTimeout执行原理说明
- Javascript引擎单线程机制及setTimeout执行原理说明
- Javascript引擎单线程机制及setTimeout执行原理说明
- JavaScript脚本代码的位置及在页面中的执行顺序
- JavaScript setTimeout 的原理
- 理解JavaScript的单线程运行机制及setTimeout(fn,0)
- Javascript中的线程以及获取动态Dom元素的问题--thread/appendChild/setTimeout
- setTimeout及Js的工作原理
- javascript 中的 setTimeout和setInterval的使用
- javaScript 线程的执行
- JavaScript在网页中的位置
- JavaScript在HTML中的位置
- JavaScript中的setTimeout函数
- JavaScript的执行原理
- 前端复习--javascript 任务队列 与 setTimeout()的深入学习
- JavaScript中的setTimeOut,及5个常用实例
- C#线程 在某一时间内,只有N个线程在并发执行,其余都在队列中的实现
- java静态代理和动态代理(jdk,cglib)
- 共享数据的保护 利用const
- Duilib学习之仿酷狗开发(3)
- 【第三方Jar包】poi简介
- kafka一些常用命令(持续更新)
- setTimeout的原理及在JavaScript线程执行队列中的位置
- PHP的编译安装
- 第3章 启程——Windows编程基础(下)
- QT界面,鼠标滚轮实现缩放问题
- ASCII
- 副本dp
- ext6.2 关闭窗口
- 【DOM 编程艺术】4 案例探究:JavaScript图片库
- 友盟第三方实现qq等分享