今天来说一下事件循环机制。
这个词虽然可能平时常见不到,但是其实每一天都在被应用中。
举个🌰
var a = 'tian';
console.log('a:', a); // tian
是不是觉得很简单,下一个🌰
setTimeout(function () {
var b = 'tian0225';
console.log(b); // tian0225——2
}, 0)
var a = 'tian';
console.log('a:', a); // tian——1
也不难吧,最后一个🌰
var a = 'tian';
console.log('a:', a); // tian
setTimeout(function () {
var b = 'tian0225';
console.log('b:', b); // tian0225
})
new Promise(function(resolve){
var c = 'TIAN';
console.log('c:', c); // TIAN
resolve();
}).then(function() {
var d = 'TIAN0225';
console.log('d', d); // TIAN0225
});
console.log('end');
这个的结果呢?是不是有点乱,结果是这样的呦~
/*
a:tian ——1
c:TIAN ——2
end ——3
d:TIAN0225 ——4
b:tian0225 ——5
*/
是不是会觉得有点好奇,为什么会是这样的,跟自己想象的不太一样。这就是Event Loop搞的事情。
首先,JS不是“耿直的”自上而下执行,要考虑要异步,声明等问题。此时,就出现了2个词汇宏任务
和微任务
。
怎么解释这两个词呢,打个比方。
假设循环事件这个过程就是在某处办业务,宏任务就是你的主要任务,微任务是你在办完主要任务后的附加任务。
比如:我要充100话费、充了话费之后,顺带手充了个流量。
充话费(宏任务)=> 充流量(微任务)
在代码中是什么样子呢?
大概是这样,把setTimeout, Promise等任务分成宏任务,内部的逻辑及后续就是微任务。这些宏任务的执行顺序是按照“上下执行”顺序来决定的。
举个例子🌰:
setTimeout(function() {
console.log('这是timeout异步任务');
})
new Promise(function(resolve) {
console.log('这是promise同步任务');
resolve();
}).then(function() {
console.log('这是promise异步任务1');
}).then(function() {
console.log('这是promise异步任务2');
}).then(function() {
console.log('这是promise异步任务3');
})
console.log('这是同步任务');
答案~
这是promise同步任务
这是同步任务
这是promise异步任务1
这是promise异步任务2
这是promise异步任务3
这是timeout异步任务
为什么是这个结果呢,真实效果是这样?
首先执行的是宏任务0:这是一个整体的script检测,setTImeout这是个异步任务,直接记录到宏任务1,这样的话0的真实执行环境就是这样:
- 看到了
setTimeout
,setTimeout
具备后置盘它体制(异步),先盘其他人,把它放到了宏任务队列里面。 - 继续往下,看到了
new promise
有个console.log('这是promise同步任务')
可以盘,盘它! - 继续往下,嗯?它有几个
.then()
微任务啊,直接拿走放到了微任务队列里面,之后再盘。new promise
就这样被盘没了。 - 继续往下看。嗯?有个
console.log('这是同步任务')
可以盘,盘它! - 继续往下,嗯?没得盘了,找找有没有之前要盘的,翻了翻微任务队列。
- 哎?之前有3个
.then()
可以盘,盘它! - 好吧,盘完了之后微任务队列里面没得盘了。从宏任务队列里找下一个继续盘吧。
- 此时!在宏任务队列里面的是啥,就是一开始被放进去的
setTimeout
。so...就这样开始了setTimeout的盘它之旅....
Event Loop(事件循环机制)就这样讲完了,看起来很复杂,其实很简单,前一段写的很理论,最后一段的小故事写的很满意,以后还是写故事吧~有问题请评论,有机会的话可能会把这一段写成个完整的故事。
网友评论