事件循环是什么?
为什么有事件循环机制
因为js是单线程的,注意,浏览器是多线程的。浏览器只给一个线程给js渲染,
假设是多线程,可能会存在这种情况:
若一个线程要操作dom,另一个线程要删除dom,就会发生冲突。
既然是单线程的,那么代码执行就只能自上至下一行行执行(同步)吗? 遇到一些异步的如何处理?
这时,就需要event loop来实现非阻塞执行。
对着上面的三行代码,我们可以说一下什么是事件循环机制。
首先,执行第一句代码同步代码,1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)(调用栈),然后执行并在控制台输出;
执行第二句时,setTimeout是个web API,即会设置一个3秒的定时器;
执行第三句同步代码,同样会被放到调用栈中,然后执行并在控制台输出;
这时调用栈是空的,event Loop做 循环时,发现任务队列中是空的,则不执行;
等过了3秒后,callback会被放入到任务队列中,系统在做循环时候,会发现里面有一条任务,会将它放入到调用栈中,执行它,并在控制台中输出;
Event Loop简而言之就是循环任务队列中,若里面有任务,且调用栈为空的情况下,会把回调函数放到调用栈中并执行。直到循环队列为空。
在事件循环当中有两种任务:
- 宏任务
- 微任务
宏任务:整体代码,setTimeout,setInterval,I/O操作 ajax;
微任务:new promise().then()/catch中的回调 ,await有结果后的语句。
为什么需要两种任务,为什么不能只有宏任务?
宏任务只能按照先进先出的原则执行,一些高优先级的任务就无法先执行。还需要执行优先级更高的。于是还要有微任务。
一道题目
async function async1() {
console.log('async1 statrt');//2.打印出来
await async2();//3.执行async2,等待返回结果
//await后的可看做nw Promise中语句,直接执行
//awiat下面的部分看做promsie.then中的部分
console.log("async1 end");//微任务异步 6.执行第一个微任务
}
async function async2() {
console.log('async2')
}
console.log('script start');//1.打印script start
setTimeout(() => {
console.log('setTimeout');//宏任务 8.执行第一个宏任务
}, 0);
async1();
new Promise(function (resolve) {
console.log('promise1');//4.打印出promise1
resolve();
}).then(function () {
console.log('primise2');//微任务 7.执行第二个微任务
})
console.log("script end");//5.打印出script end
代码运行如下: