从Extjs defer看浏览器阻塞和计时器 推荐
2014-01-13 10:27
155 查看
ext版本2.1
1.今天同学让我检查一段代码,大意如下:
他的意图是,先做第0件事,然后延迟1秒做第一件事情;做完第一件事之后,延迟一秒做第二件事。
2. 问题出现在something2比something1延迟不到1秒钟,代码如下:
结果如下图:
![](http://s3.51cto.com/wyfs02/M02/11/80/wKiom1LTQGShLHT3AABgSaCxlzs251.jpg)
由图可以看出,something2比something仅仅延迟1毫秒。something1比something0延迟将近3秒。
3. 后者是因为,something1计时器到的时候,浏览器被阻塞了,导致了something1的拖后执行。
代码如下:
在something1和something0之间加入了一个alert方法,他会阻塞浏览器,结果如下图:
![](http://s3.51cto.com/wyfs02/M00/11/80/wKioL1LTQ3nzlRNVAABvgtEGUQk386.jpg)
4. something1延迟了17秒多。注:这只是表象,实际上alert()事件阻止了浏览器,导致mark A不能被扫描,事件不能被执行。当alert()接触阻止的时候,浏览器会继续扫描、执行mark A,并设置计时器,1秒钟之后执行内部方法。所以,无论alert()阻止多长时间,mark A内部的方法都会执行,并且比扫描时间延迟1秒钟执行。
5. 一个更明显一点儿的例子:
把alert放到了something2中,结果如下图:
![](http://s3.51cto.com/wyfs02/M00/11/80/wKiom1LTRyWzOGhzAABqhvPTlNw836.jpg)
6. 会不会在阻止浏览器执行期间,计时器时间到而执行延迟方法呢?代码修改如下:
浏览器会顺序扫描代码,把mark A放入事件队列,然后把mark B 放入事件队列,再执行alert阻塞浏览器。等待几秒钟之后,解除浏览器。然后something1和something2会按照顺序分别执行(没有再次延时1秒)。
结果如下图:
![](http://s3.51cto.com/wyfs02/M00/11/81/wKiom1LTSsDjyF3aAABRLu7z50Q944.jpg)
小结:浏览器阻止,会导致计时器事件的拖后执行,而不是按照计时器时间执行,也不是不执行。原因,可能跟事件队列有关系,并且虽然拦浏览器被阻止,但是计时器仍然正常计时,时间到的时候,会把事件放入到事件队列。一旦浏览器接触阻止,便会依次执行事件队列的事件。这是个人的想法,以后再考证。
上面说的是阻塞浏览器对计时器的影响,计时器是写在ext defer方法中的。
7. Ext defer 定义如下:
简单的例子:
defer方法的重点就是计时器,在这之前产生一个事件代理,代码如下:
事件代理的作用就是给事件的this绑定对象,给事件传递参数。
8. JS setTimeout:延迟调用方法
语法如下:
例子如下:
可见,setTimeout在回调func的时候,会把方法的this指向window,所以需要重新绑定对象。
同时还设计传递参数、浏览器版本等问题,详见MDN https://developer.mozilla.org/en-US/docs/Web/API/Window.setTimeout
9. 按照同学的意图,代码应该写成下面的样子,涉及到异步编程的问题,这里忽略不计
1.今天同学让我检查一段代码,大意如下:
// do something 0 (function(){ // do something 1 }).defer(1000); (function(){ // do something2 }).defer(1000);
他的意图是,先做第0件事,然后延迟1秒做第一件事情;做完第一件事之后,延迟一秒做第二件事。
2. 问题出现在something2比something1延迟不到1秒钟,代码如下:
var start = new Date().getTime(), end, dur; console.log('开始的时间是:'+ start); // something 0 (function(){ // mark A end = new Date().getTime(); dur = end - start; console.log('第一次defer执行的时间为:' + end + ' 时间差为:' + dur); }).defer(1000); (function(){ // mark B start = new Date().getTime(); dur = start - end; console.log('第二次defer执行的时间为:' + start + ' 时间差为:' + dur); }).defer(1000);
结果如下图:
![](http://s3.51cto.com/wyfs02/M02/11/80/wKiom1LTQGShLHT3AABgSaCxlzs251.jpg)
由图可以看出,something2比something仅仅延迟1毫秒。something1比something0延迟将近3秒。
3. 后者是因为,something1计时器到的时候,浏览器被阻塞了,导致了something1的拖后执行。
代码如下:
var start = new Date().getTime(), end, dur; console.log('开始的时间是:'+ start); // something 0 alert('10秒钟之后再点我!'); // 浏览器阻塞 (function(){ // mark A end = new Date().getTime(); dur = end - start; console.log('第一次defer执行的时间为:' + end + ' 时间差为:' + dur); }).defer(1000); (function(){ // mark B start = new Date().getTime(); dur = start - end; console.log('第二次defer执行的时间为:' + start + ' 时间差为:' + dur); }).defer(1000);
在something1和something0之间加入了一个alert方法,他会阻塞浏览器,结果如下图:
![](http://s3.51cto.com/wyfs02/M00/11/80/wKioL1LTQ3nzlRNVAABvgtEGUQk386.jpg)
4. something1延迟了17秒多。注:这只是表象,实际上alert()事件阻止了浏览器,导致mark A不能被扫描,事件不能被执行。当alert()接触阻止的时候,浏览器会继续扫描、执行mark A,并设置计时器,1秒钟之后执行内部方法。所以,无论alert()阻止多长时间,mark A内部的方法都会执行,并且比扫描时间延迟1秒钟执行。
5. 一个更明显一点儿的例子:
var start = new Date().getTime(), end, dur; console.log('开始的时间是:'+ start); // something 0 (function(){ // mark A end = new Date().getTime(); dur = end - start; console.log('第一次defer执行的时间为:' + end + ' 时间差为:' + dur); }).defer(1000); (function(){ // mark B alert('10秒钟之后再点我!'); // 浏览器阻塞 start = new Date().getTime(); dur = start - end; console.log('第二次defer执行的时间为:' + start + ' 时间差为:' + dur); }).defer(1000);
把alert放到了something2中,结果如下图:
![](http://s3.51cto.com/wyfs02/M00/11/80/wKiom1LTRyWzOGhzAABqhvPTlNw836.jpg)
6. 会不会在阻止浏览器执行期间,计时器时间到而执行延迟方法呢?代码修改如下:
var start = new Date().getTime(), end, dur; console.log('开始的时间是:'+ start); // something 0 (function(){ // mark A end = new Date().getTime(); dur = end - start; console.log('第一次defer执行的时间为:' + end + ' 时间差为:' + dur); }).defer(1000); (function(){ // mark B start = new Date().getTime(); dur = start - end; console.log('第二次defer执行的时间为:' + start + ' 时间差为:' + dur); }).defer(1000);
alert('10秒钟之后再点我!'); // 浏览器阻塞
浏览器会顺序扫描代码,把mark A放入事件队列,然后把mark B 放入事件队列,再执行alert阻塞浏览器。等待几秒钟之后,解除浏览器。然后something1和something2会按照顺序分别执行(没有再次延时1秒)。
结果如下图:
![](http://s3.51cto.com/wyfs02/M00/11/81/wKiom1LTSsDjyF3aAABRLu7z50Q944.jpg)
小结:浏览器阻止,会导致计时器事件的拖后执行,而不是按照计时器时间执行,也不是不执行。原因,可能跟事件队列有关系,并且虽然拦浏览器被阻止,但是计时器仍然正常计时,时间到的时候,会把事件放入到事件队列。一旦浏览器接触阻止,便会依次执行事件队列的事件。这是个人的想法,以后再考证。
上面说的是阻塞浏览器对计时器的影响,计时器是写在ext defer方法中的。
7. Ext defer 定义如下:
defer : function(millis, obj, args, appendArgs){ var fn = this.createDelegate(obj, args, appendArgs); // 事件代理,this指向的是调用defer的方法,如下例的sayHi if(millis){ return setTimeout(fn, millis); // 重点:计时器 } fn(); return 0; }
简单的例子:
var sayHi = function(name){ alert('Hi, ' + name); }; // executes after 2 seconds: sayHi.defer(2000, this, ['Fred']);
defer方法的重点就是计时器,在这之前产生一个事件代理,代码如下:
createDelegate : function(obj, args, appendArgs){ var method = this; // 注意 return function() { var callArgs = args || arguments; if(appendArgs === true){ callArgs = Array.prototype.slice.call(arguments, 0); callArgs = callArgs.concat(args); }else if(typeof appendArgs == "number"){ callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first var applyArgs = [appendArgs, 0].concat(args); // create method call params Array.prototype.splice.apply(callArgs, applyArgs); // splice them in } return method.apply(obj || window, callArgs); // 注意,绑定对象 }; }
事件代理的作用就是给事件的this绑定对象,给事件传递参数。
8. JS setTimeout:延迟调用方法
语法如下:
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]); var timeoutID = window.setTimeout(code, delay);
例子如下:
var Person = function(){ this.addr = 'wy'; this.age = '18'; this.sayHi = function(){ console.log('addr:' + this.addr +' age:' + this.age); console.log(this == window); }; }; per = new Person(); per.sayHi(); // addr:wy age:18; false setTimeout(per.sayHi,1000); // addr:undefined age:undefined; true
可见,setTimeout在回调func的时候,会把方法的this指向window,所以需要重新绑定对象。
同时还设计传递参数、浏览器版本等问题,详见MDN https://developer.mozilla.org/en-US/docs/Web/API/Window.setTimeout
9. 按照同学的意图,代码应该写成下面的样子,涉及到异步编程的问题,这里忽略不计
// do something 0 (function(){ // do something 1 (function(){ // 写在里面 // do something2 }).defer(1000); }).defer(1000);
相关文章推荐
- 源码推荐(0525):功能完善使用简单的图片浏览器,MJExtension用法
- 基于浏览器的html在线编辑器 热点推荐
- 再推荐一款不错的虚拟PDF打印机和PDF浏览器~!
- javascript浏览器对象之计时器
- 蛙蛙郑重推荐您使用firefox浏览器
- ajax错误提示一闪而过,ajax请求数过多引起浏览器无响应(阻塞)问题解决
- 推荐两个开发用的浏览器插件
- 浏览器兼容测试最坑爹,费时费力;今天推荐一个在线的浏览器兼容测试服务
- 【推荐】两款强大的浏览器插件
- jquery插件推荐浏览器嗅探userAgent
- 必须要推荐的浏览器插件---作者:marsggbo
- 向大家推荐好的浏览器浏览csdn
- 线程工具类-通过信号量、计时器等机制控制多线程之间的运行阻塞-笔记整理11
- 10个免费的跨浏览器测试工具推荐
- 兼容多浏览器的JS 浮动广告[推荐]
- 浏览器加载js的阻塞与非阻塞
- 给Flash加一个超链接(推荐使用透明层)兼容主流浏览器
- 抢票浏览器该不该禁? 推荐
- 玩转 浏览器 10款国际流行插件推荐