setTimeout(function(){console.log(1);}, 0);
console.log(2);
这段代码的运行结果是2,1,而不是1,2,这是因为js的执行机制。
首先,我们知道js是单线程的,即同时只能处理一件事,但是浏览器是多线程的,那js为什么不能是多线程呢,主要因为js处理用户的简单交互,如果同时处理多个事件就很容易造成混乱。
js处理时间可以分成主线程和任务队列(也可以叫等待队列),一个一个地处理主线程中的任务,等到主线程中的任务都执行完了,再执行等待队列中的任务。在主线程执行过程中如果任务队列有任务完成了则自动进入主线程排队等待执行,但像定时器如果设置了执行时间,如果等待队列中轮到他进入主线程执行,也要先等待他的延迟时间再进入主线程执行。主线程从任务队列中源源不断的读取事件,这个过程是循环的,于是也叫事件循环Event Loop.
var req = new XMLHttpRequest();
req.open('GET', url);
req.send();
req.onload = function (){};
req.onerror = function (){};
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function (){};
req.onerror = function (){};
req.send();
这两段代码结果是一样的。
前面说的定时器,包括setTimeOut和setInterval执行机制是一样的,比如setTimeOut(function(){},0),第一个参数是回调函数,第二个是延迟执行的毫秒数。延迟时间为0不代表不延迟,直接执行,而是在能执行的时候立即执行,即主线程和等待队列中他前面的任务都执行完才可以。
———-分割线—————-
2018.1.12
看的多了,发现自己为了理解简单,对js的执行机制理解的太片面了,有这样一道题
setTimeout(function(){console.log(4)},0);
new Promise(function(resolve){
console.log(1)
for( var i=0 ; i<10000 ; i++ ){
i==9999 && resolve()
}
console.log(2)
}).then(function(){
console.log(5)
});
console.log(3);
运行结果是1,2,3,5,4
这里跟microtask(微观)和macrotask(宏观)有关
具体就是这样子的了,
记得以前看过一篇关于microtask和macrotask的文章,当时还觉得很空,就随便一看过去了,结果现在又用到了,而且不会了