JavaScript的setTimeout与setInterval执行时机
继前篇 谈谈JavaScrip的异步实现,我们知道JavaScript引擎是单线程的,所有的js的代码都将在这个单线程中执行。像浏览器事件、计时器等异步只是个幌子,异步时js并没有多个线程在执行,而是都排列在一个待执行队伍中。
setTimeout的使用方法
setTimeout(function(){},time)--可以正确执行。
setTimeout("js语句",time)--可以正确执行。 js语句可以是多条语句。
setTimeout(fun,time)
只引用函数名字,也可运行,但是要注意的是:如果fun是某个对象的方法,则fun函数内的this此时被当做window。
eg:
var obj ={"p1": "obj的属性p1","fun": function() {alert(this.p1);} };setTimeout(obj.fun,1000);
运行后的结果,是undefined。用函数式对象定义对象也是此种结果。用方法1则可以输出正确的结果。
setTimeout(fun(),time)--不正确使用
不能正确执行,因为fun()会立即执行,没有延迟time时间后执行。
执行时机
当页面初始化时,setTimeout与setInterval的回调与队列中其它回调执行次序是怎样的?《JavaScript权威指南》中介绍的,setTimeout的回调发生在所有的事件都处理完,这句到底是不是对的?带着这些疑问,我们先来看个例子:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 <metahttp-equiv="content-type"content="text/html;charset=utf-8"> 6 <scripttype="text/javascript"src="a.js"></script> 7 <scripttype="text/javascript"> 8 varbefore_x= 2;9 </script> 10 <scripttype="text/javascript"> 11 varmiddle_x=3;12 //页面head中js执行完毕后,执行队列(页面尾部的js,定时器回调、事件回调,究竟哪个先执行,这个随机的); 13 setTimeout(function(){14 console.log("Timeout:"+(ax+before_x+middle_x+middle_y+bx+cx+domLoad_x+inner_x));15 },0);16 varinter=setInterval(function(){17 console.log("Interval:"+(ax+before_x+middle_x+middle_y+bx+inner_x+domLoad_x+cx));18 clearInterval(inter);19 },1)20 varmiddle_y=1;21 </script> 22 <scripttype="text/javascript"src="b.js"></script> 23 </head> 24 <body> 25 <inputtype="text"id="inp_click"onclick="inner_x =1;for(var i=0;i<1000000;i++){inner_x++};console.log('clickEvent:'+inner_x);"> 26 </body> 27 </html> 28 <scripttype="text/javascript"src="c.js"></script> 29 <scripttype="text/javascript"> 30 varstart_time= newDate().getTime();31 for(vari= 1;i<1000000;i++){32 33 }34 varend_time= newDate().getTime();35 console.log('after the html,wait:'+(end_time-start_time));36 varinp=document.getElementById("inp_click");37 varevent=document.createEvent("MouseEvent");38 event.initMouseEvent("click",true,true,document.defaultView,0,0,0,0,0,false,false,false,false,0,null);39 inp.dispatchEvent(event);40 vardomLoad_x= 4;41 </script>
a.js
1 var ax =1;
b.js
1 var bx = 2;
c.js
1 var cx =3;
chrome中绝大数执行正常;
偶尔会报错,特别是在页面刚在浏览器中打开时,出现以下错误
为什么正常?这是因为计时器在所有的js都执行完后才执行,包括页面尾部的js,模拟触发的事件回调。
为什么报错?这是因为计时器在页面尾部js执行前,先执行。
结论:页面head中js执行完毕后,执行队列(页面尾部的js,定时器回调、事件回调),究竟哪个先执行,这个随机的。《JavaScript高级程序设计》介绍到DomContentLoaded事件时,提到了setTimeout(function(){ //此处添加事件处理程序代码},0);用以弥补老式浏览器不支持DomContentLoaded。 如果你们还有兴趣,我们再来看个例子,至于为什么是这样,大家自己去思考。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 <metahttp-equiv="content-type"content="text/html;charset=utf-8"> 6 <scripttype="text/javascript"src="a.js"></script> 7 <scripttype="text/javascript"> 8 varbefore_x= 2;9 (function(window, undefined) {10 varreadyList=[],11 isReady= 0,12 readyBound= false,13 init,14 bindReady,15 readyWait= 1;16 init= function(wait) {//A third-party is pushing the ready event forwards 17 if(wait=== true) {18 readyWait--;19 }//Make sure that the DOM is not already loaded 20 if(!readyWait||(wait!== true && !isReady)) {//Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 21 //确保body元素存在,这个操作是防止IE的bug 22 if(!document.body) {23 returnsetTimeout(init,1);24 }//dom渲染完成标志设置为true 25 isReady= true;//If a normal DOM Ready event fired, decrement, and wait if need be 26 if(wait!== true && --readyWait> 0) {27 return;28 }//绑定的渲染完成后的执行函数 29 if(readyList) {//全部执行 30 varfn, i= 0,31 ready=readyList;//重置 32 readyList= null;33 while((fn=ready[i++])) {34 fn.call(document);35 }36 }37 }38 };//初始化readyList事件处理函数队列 39 //兼容不同浏览对绑定事件的区别 40 bindReady= function() {41 if(readyBound) {42 return;43 }44 readyBound= true;//$(document).ready()的嵌套调用时 45 //readyState: "uninitalized"、"loading"、"interactive"、"complete" 、"loaded" 46 if(document.readyState=== "complete") {//让它异步执行,使这个ready能延迟 47 returnsetTimeout(init,1);48 }//Mozilla, Opera and webkit 49 //兼容事件,通过检测浏览器的功能特性,而非嗅探浏览器 50 if(document.addEventListener) {//使用事件回调函数 51 document.addEventListener("DOMContentLoaded",52 function() {53 document.removeEventListener("DOMContentLoaded", arguments.callee,false);54 init();55 },56 false);//绑定回调到load,使之能一定执行 57 window.addEventListener("load", init,false);//IE 58 }else if(document.attachEvent) {//确保在load之前触发onreadystatechange, 59 //针对iframe情况,可能有延迟 60 document.attachEvent("onreadystatechange",61 function() {//Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 62 if(document.readyState=== "complete") {63 document.detachEvent("onreadystatechange", arguments.callee);64 init();65 }66 });//绑定回调到一定执行能load事件 67 window.attachEvent("onload", init);//如果是IE且非iframe情况下 68 //持续的检查,看看文档是否已准备 69 vartoplevel= false;70 try{71 toplevel=window.frameElement== null;72 }catch(e) {}73 (function() {74 if(document.documentElement.doScroll&&toplevel) {75 if(isReady) {76 return;77 }78 try{//If IE is used, use the trick by Diego Perini 79 //http://javascript.nwbox.com/IEContentLoaded/ 80 document.documentElement.doScroll("left");81 }catch(e) {82 setTimeout(arguments.callee,1);83 return;84 }//执行在等待的函数 85 init();86 }87 })();88 }89 };90 window.ready= function(fn) {//绑定上监听事件 91 bindReady();//如果dom已经渲染 92 if(isReady) {//立即执行 93 fn.call(document);//否则,保存到缓冲队列,等上面的监听事件触发时,再全部执行 94 }else if(readyList) {//将回调增加到队列中 95 readyList.push(fn);96 }97 };98 })(window);99 </script> 100 <scripttype="text/javascript"> 101 varmiddle_x=3;102 //页面head中js执行完毕后,执行队列(页面尾部的js,定时器回调、事件回调,究竟哪个先执行,这个随机的); 103 setTimeout(function(){104 console.log("Timeout:"+(ax+before_x+middle_x+middle_y+bx+cx+domLoad_x+inner_x));105 },0);106 varinter=setInterval(function(){107 console.log("Interval:"+(ax+before_x+middle_x+middle_y+bx+inner_x+domLoad_x+cx));108 clearInterval(inter);109 },5000)110 varmiddle_y=1;111 window.onload= function(event){112 console.log("onloaded");113 }114 ready(function(event){115 console.log("dom loaded");116 });117 </script> 118 <scripttype="text/javascript"src="b.js"></script> 119 </head> 120 <body> 121 <inputtype="text"id="inp_click"onclick="inner_x =1;for(var i=0;i<1000000;i++){inner_x++};console.log('clickEvent:'+inner_x);"> 122 </body> 123 </html> 124 <scripttype="text/javascript"src="c.js"></script> 125 <scripttype="text/javascript"> 126 varstart_time= newDate().getTime();127 for(vari= 1;i<1000000;i++){128 129 }130 varend_time= newDate().getTime();131 console.log('after the html,wait:'+(end_time-start_time));132 varinp=document.getElementById("inp_click");133 varevent=document.createEvent("MouseEvent");134 event.initMouseEvent("click",true,true,document.defaultView,0,0,0,0,0,false,false,false,false,0,null);135 inp.dispatchEvent(event);136 vardomLoad_x= 4;137 </script>
此时浏览器显示结果为
或者为
本文首发:http://www.cnblogs.com/sprying/archive/2013/05/29/3105268.html参考:http://www.cnblogs.com/diguonianzhu/archive/2012/06/29/2570371.html
转载于:https://www.cnblogs.com/sprying/archive/2013/05/29/3105268.html
JavaScript的setTimeout与setInterval执行时机相关推荐
- JavaScript———从setTimeout与setInterval到AJAX异步
setTimeout与setInterval执行 首先我们看一下以下代码打印结果 1 2 3 4 5 6 7 console.log(1); setTimeout(function() { conso ...
- 关于Javascript 中 setTimeout和setInterval的总结和思考
1. JavaScript 单线程 我们通常说,javascript是单线程,指的是解释和执行js代码的引擎是单线程. 而对于浏览器来说,浏览器并不是单线程的,浏览器的线程通常包括:渲染引擎线程(负责 ...
- Javascript的setTimeOut()和setInterval()的定时器用法
Javascript用来处理延时和定时任务的setTimeOut和setInterval函数应用非常广泛,它们都用来处理延时和定时任务,比如打开网页一段时间后弹出一个登录框,页面每隔一段时间发送异步请 ...
- JavaScript之setTimeout与setInterval的用法与区别
}, 1000) } 那为啥使用let就可以了呢: 其实使用let之后,也没有改变执行机制,仍然是最后执行的alert(),但是let可以在每一次把更新的变量i传进函数体内,也就是每一次的i加1之后, ...
- 如何使用定时器settimeout、setInterval执行能传递参数的函数(转)
来自: http://www.cnblogs.com/wkylin/archive/2012/09/07/2674911.html var userName="jack"; //根 ...
- JavaScript 中的 setTimeout 和 setInterval 方法
有时您不希望函数立即运行.您希望它重新执行,甚至在特定时间间隔后重复运行.JavaScript 为我们提供了两种实现方法: setTimeout 和 setInterval.下面,我们将来理解这两个方 ...
- JavaScript时间事件:setTimeout和setInterval
Programmers use timing events to delay the execution of certain code, or to repeat code at a specifi ...
- JavaScript教程-setTimeout,setInterval,
调度:setTimeout 和 setInterval 有时我们并不想立即执行一个函数,而是等待特定一段时间之后再执行.这就是所谓的"计划调用(scheduling a call)" ...
- javascript requestAnimationFrame 解决 setTimeout、setInterval 时间不准的方法。
javascript requestAnimationFrame 解决 setTimeout.setInterval 时间不准的方法. 取代 setInterval <!DOCTYPE html ...
- JavaScript定时调用函数(SetInterval与setTimeout)
setTimeout和setInterval的语法相同.它们都有两个参数,一个是将要执行的代码字符串,还有一个是以毫秒为单位的时间间隔,当过了那个时间段之后就将执行那段代码. 不过这两个函数还是有区别 ...
最新文章
- 独家 | 攀登数据科学家和数据工程师之间的隔墙
- 机器学习中的范数规则化之(二)核范数与规则项参数选择
- Python中的驻留机制:小数据池和代码块
- 用JSON.parse(JSON.stringify(itemData))序列化反序列化实现‘深度复制’
- 方法练习3_打印指定次数的HelloWorld
- spring 之 property-placeholder 分析
- 服务器操作系统与安装步骤,服务器操作系统与安装步骤
- 复制一个空洞文件且忽略掉其空洞内容
- ubuntu 的使用(五)—— 桌面(desktop)
- 愚公移山第一章伪代码
- 如何用photoshop识别图片上文字的字体
- 物料科目组设置和分配-OVK5/SM30(V_TVKM)/VKOA
- oracle ora-3136,[转]ORA-3136(WARNING Inbound Connection Timed Out)分析
- 计算机表格常用根式,excel怎么建立常用根式_在excel中怎样开根号�9�3
- OSChina 周四乱弹 ——裤子穿反就被开除了?
- Ubuntu18.04使用RPLIDAR A2M12雷达出错的解决办法
- 一个网站SEO优化方案
- Redis 性能测试
- ubuntu nginx服务器安装SSL证书
- 前后端分离php验证码