探究下setTimeout,解除使用时的顾虑感

340 阅读1分钟

日常情况

为了提升用户交互,我们会想到通过短暂的定时,反馈给用户一些惊喜。例如用户点击某个按钮,我们想给他一个定时的提醒,自然就会敲下setTimeout函数。

因为对setTimeout的理解,停留在如何调用的层次上,而又对开发包裹着一层性能美感,每次开启一个异步任务,潜意识会在内心抹一层顾虑感。

所以,javascript是如何处理setTimeout的呢?

事件循环机制

首先,javascript是一门单线程的语言,同一个时间只可能运行一段代码。异步方法会被放在一个队列中,先排队的就先被调用。 用伪代码感受下:

var eventLoop = []
var event
while(true) {
    if(eventLoop.length > 0) {
        event = eventLoop.shift()
        try {
            event()
        }
        catch(err) {
            throw err
        }
    }
}

setTimeout与事件循环的关系

setTimeout像是一个老好人,总是能在我们遇到困难的时候挺身而出,为我们实现异步的需求。却因为机制的要求,他总是不能那么精确做好需求。

例如,我们设定一个1000ms后的定时器,这个定时器的任务并不会被加到事件循环里头,而是在1000ms后,事件循环才会把任务放到队列的末尾,如果队列里已经有大量的任务了,定时器设定的任务执行时间将严重超时。