先说eventloop是什么?
javascript分两种,一种是宏任务(macro-tack),一种是微任务(miceo-tack)
- 宏任务包括:setTimeout 、script、setInterval
- 微任务包括:promise.then()
- 事件执行顺序,先执行宏任务,在执行微任务,任务又分同步任务和异步任务,同步任务进入主线程,异步任务进入Event Tbale并注册函数,异步事件结束后,会将回调函数,放到event Queue中(宏任务和微任务是不同的Event Queue),同步任务执行完毕后,会从Event Queue中读取事件放入主线程执行,
在说下任务队列。
-所有的同步任务都在主线程上,形成一个执行栈。
-主线程之外还有个任务队列,只要异步任务有了结果,就会在任务队列中放一个事件
当执行栈的任务执行完毕了,就去任务队列中,看下有没有需要执行的事件,如果有的话,就结束了等待。进入执行栈,进行执行。
1591355289(1).jpg
下面的函数打印值都为4
for (var i = 0; i < 4; i++) {
setTimeout(function() {
console.log(i);
}, 300);
}
原因:js 执行的时候首先会先执行主线程,异步相关的会存到异步队列里,当主线程执行完毕开始执行异步队列, 主线程执行完毕后,此时 i 的值为 4,说以在执行异步队列的时候,打印出来的都是 4;
需要注意的是,setTimeout()只是将事件插入了"任务队列",必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。要是当前代码耗时很长,有可能要等很久,所以并没有办法保证,回调函数一定会在setTimeout()指定的时间执行。
-这也考了闭包,可以通过改为立即执行函数
for (var i = 0; i < 4; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 300);
})(i);
}
//这样的打印结果就是 0 1 2 3
网友评论