setTimeout可以将字符串当成代码执行,类比eval函数。当遇到setTimeout或者SetInterval,他们会进入宏任务队列,此时,函数不执行,但是他们的时间会开始计算

发布时间 2023-11-16 10:28:11作者: 龙陌

请问以下JS代码的输出顺序是?

let date = new Date()
setTimeout(() => {
    console.log('1')
}, 2000)
setTimeout('console.log(2)',1000);
setTimeout(function() {
  console.log('3')
}, 1500);
while((new Date() - date) < 3000) {}

A
报错

B
3秒以后同时输出2 3 1

C
1秒后输出2,1.5秒后输出3,2秒后输出1

D
4秒后输出2,4.5秒后输出3,5秒后输出1

正确答案:B

需要明确一点的是setTimeout可以将字符串当成代码执行,类比eval函数。
While所在是微任务,所以前3秒后在执行while函数,
setTimeout函数虽然在各自对应时间后插入了队列,但是由于属于宏任务所以暂时还没有执行,直到while微任务完成,才按顺序输出。

在执行前八行代码的时候在回调函数队列里面依次添加三个回调函数,此时回调函数队列为【2,3,1】

然后在while循环里面停留三秒,这时已经把回调函数队列里面的三个回调函数的等待时间都花光了,等循环停留三秒结束后,立刻执行回调函数队列里面的函数,所以3秒以后同时输出2 3 1。

evenLoop,当遇到setTimeout或者SetInterval,他们会进入宏任务队列,此时,函数不执行,但是他们的时间会开始计算。如果程序微任务或者代码运行时间过长,那么执行宏任务时他们会直接执行