app资讯
您的当前位置:首页JS的 setTimeout你理解了吗?

JS的 setTimeout你理解了吗?

来源:app资讯


在了解了 JS 是单线程执行任务之后,我们来看以下一个案例。我们猜测一下以上代码运行后的结果会是怎样的。timer1 指的是在500毫秒之后会在控制台打印出 3 , timer2 会在1000毫秒之后打印数字 4 ,在 console.log(1) 和 console.log(2) 之间插入一个运行2000毫秒但是不做任何操作的函数。所以我们预测得输出结果就是:

但是实际的运行结果不会是我们预测的那样,实际我们会看到这样的运行结果。所以 JS 在运行程序的时候好像跟我们预想的不太一样,到底是为什么会有这样的结果呢?

ps:请直接在浏览器的控制台里运行上面的代码,不要用 jsbin 之类的在线 js 调试网站,否则可能看不到真实的效果。比如我用 jsbin 跑的结果,直接对useTime 函数内的循环进行了优化,“甚至加上了//noprotection 也没啥用”。

js是单线程的脚本语言。

在搞清楚以上的程序为什么会有跟我们预想不一样的结果之前,我们先得了解一个事实 —— JS是单线程的。单线程是 JavaScript 语言的一大特性,而单线程的意思就是同一个时间里只能做一件事。至于 JS 为什么是单线程的,就要从 JS 的来源去理解了。JS 本来设计就是作为浏览器的脚本语言,主要是为了负责网页的行为,操作DOM元素。那我试想一下,如果 JS 被设计为多线程,在操作DOM元素的时候,一个线程需要对某个元素进行修改,另一个线程需要删除这个DOM元素,这样浏览器就傻眼了,“我到底该听谁的”,会造成很多不必要的麻烦。所以 JS 设计成单线程,避免了很多这样的问题。

理解了以上的原理,就可以很清晰的理解 JS 的执行顺序了,再看以下几个案例。

结果:先输出2,再输出1,中间几乎没有时间间隔。过程:首先第一个定时器,把console.log(1) 放入任务队列等着,然后接着执行执行栈内的任务——console.log(2) ,等执行栈内的任务结束了,再去看任务队列的console.log(1)。

结果:不会输出end ,程序卡死在while循环内。过程:首先t = true ,接着定时器在1000毫秒之后把t = false 放入任务队列,此时的t 仍然是true ,接着进入 while 循环,由于 t 的值是true ,所以一直在执行循环,并且出不来,结果就是卡死在循环内。
显示全文