js中的任务队列
例如以下代码
const useTime = t => {
let start = Date.now()
while(Date.now() - start < t) {}
}
let timer1 = setTimeout(() => {
console.log(3)
}, 500)
let timer2 = setTimeout(() => {
console.log(4)
}, 1000)
console.log(1)
useTime(2000)
console.log(2)
这里执行的结果就是先输出1,2秒之后依次输出2,3,4
这是为什么呢,因为js是单线程的,这里的代码我们需要依次进行执行,先创建useTime、timer1、timer2函数,创建的时候发现timer1和timer2是第三方计时模块管理的,然后将timer1、timer2放入任务队列中等待执行,之后我们输出log1,输出完之后我们再去执行useTime这个函数,因为这个函数延时写了2000毫秒,在这2000毫秒里面由第三方计时模块管理的timer1与timer2他们的延时分别是500毫秒与1000毫秒,小于2000毫秒,所以在计算useTime这个函数的时候,处于任务队列里面的timer1与timer2已经计算完成,等待取出,2000毫秒过去之后useTime这个函数已执行完成,后面就得执行log2,log2执行完成之后系统会去任务队列里面取timer1与timer2的执行结果,这些代码执行的之间都非常短,所以在我们肉眼判断中是先输出1,2秒后依次执行2,3,4。
再例如
let timer1 = setTimeout(() => {
console.log(3)
}, 1000)
let timer2 = setTimeout(() => {
console.log(4)
}, 2000)
let timer3 = setTimeout(() => {
console.log(1)
}, 0)
console.log(2)
这里代码的执行结果是先输出2,之后立即输出1,1000毫秒后输出3,2000毫秒后输出4,为什么不是1先输出呢,因为在创建函数的时候系统判断出他是定时器,直接就把他放在任务队列中去,然后先执行主线程,等主线程执行完之后才会任务队列里面依次执行。
再例如
let t = true
setTimeour(() => {
t = false
}, 1000)
while(t){}
console.log(1)
这里的代码,永远都无法输出log1,因为系统判断出他是定时器,会自动放到任务队列中去,而任务队列中的所有都得等主线程执行完之后才会去取,这里的while循环一直返回true,会一直执行下去,陷入死循环,所以永远都无法执行任务队列中的函数,所以log1也永远无法输出。
本内容参考来自饥人谷