setTimeout(fn,0)

作者 likaiqiang 日期 2017-03-24
setTimeout(fn,0)

我们都知道javascript是单线程的,浏览器端js的解析引擎在解析js时分为同步任务与异步任务。

同步任务:按照代码顺序执行。

异步任务:js中的事件回调、setInterval、setTimeout这些异步函数。

那么js引擎是怎么执行这些同步、异步任务呢?举个例子

var a = 123;
var b = 456;
setTimeout(()=>{
console.log(a);
},1000)
console.log(b);

先输出456,后输出123

这段代码可能早就见怪不怪了,但是为什么会这样呢?再举个例子

var a = 123;
var b = 456;
var c = 789;
setTimeout(()=>{
console.log(a);
},1000)
setTimeout(()=>{
console.log(c);
},0)
console.log(b);

输出顺序一次为:456、789、123

你也许会想setTimeout(fn,0)难道不会立即执行,其实js引擎处理同步、异步有它自己的一套东西。

所有的同步任务js都把他们放到一个执行栈里,在执行栈外面有个任务队列用来执行异步任务。等到执行栈运行结束,js立马会执行任务队列里面的代码。执行栈只会执行一次,而任务队列会循环调用。

用一张图来表示:

左图是执行栈,右图是任务队列,当执行栈中有异步任务时,会把他们按照顺序逐个入队,等到执行栈中的代码执行完毕,会到任务队列中按照”先入先出,后入后出”的原则执行。

这就解释了为什么setTimeout(fn,0)不会立即执行的原因

参考资料:

event loop