延时执行settimeout是javascript中的一道利器,很多时候一旦解决不了我们便会使用settimeout,但是对settimeout的理解上,很多初学的朋友有一定误区
初学的朋友一般认为settimeout是在多少毫秒后便会被执行,事实上其后面的数据代表的是一个时间片,或者说是优先级,settimeout的回调会在主干程序之后执行
比如:
var a = 0, b = 1;
setInterval(function () {
a = 1;
}, 0)
while (1) {
//...
b++;
if(a == 1)
break;
}
以下代码会导致浏览器假死,因为settimeout中的代码永远不会执行
settimeout真正的的用法是:
① 延时请求,减少不必要的请求
② 需要过多的操作dom结构时,为了闭包浏览器假死,可以使用settimeout
另外,zepto中有一段与settimeout有关的耻辱代码,在模拟tap事件时候,zepto使用dom模拟click事件的方式实现了:
.on('touchend MSPointerUp pointerup', function(e){
if((_isPointerType = isPointerEventType(e, 'up')) &&
!isPrimaryTouch(e)) return
cancelLongTap()
// swipe
if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
(touch.y2 && Math.abs(touch.y1 - touch.y2) > 30))
swipeTimeout = setTimeout(function() {
touch.el.trigger('swipe')
touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
touch = {}
}, 0)
// normal tap
else if ('last' in touch)
if (deltaX < 30 && deltaY < 30) {
tapTimeout = setTimeout(function() {
var event = $.Event('tap')
event.cancelTouch = cancelAll
touch.el.trigger(event)
if (touch.isDoubleTap) {
if (touch.el) touch.el.trigger('doubleTap')
touch = {}
}
else {
touchTimeout = setTimeout(function(){
touchTimeout = null
if (touch.el) touch.el.trigger('singleTap')
touch = {}
}, 250)
}
}, 0)
} else {
touch = {}
}
deltaX = deltaY = 0
})
比较狗血的是,他在tap这里使用了settimeout,导致了一个延时,这个延时效果直接的影响便是其event参数失效。也就是这里,touchend时候传入的event参数不会被tap事件用到,什么e.preventDefault之类的操作便于tap无关了。