javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JS事件循环

一篇文章让你搞清楚JavaScript事件循环

作者:诸葛小愚

通过JS的事件循环机制,可以更清楚JS代码的执行流,下面这篇文章主要给大家介绍了关于如何通过一篇文章让你搞清楚JavaScript事件循环的相关资料,需要的朋友可以参考下

前言

异步函数也是有执行顺序的。本质上来说,JavaScript是单线程语言,不管是在浏览器中还是nodejs环境下。浏览器在执行js代码和渲染DOM节点都是在同一个线程中,执行js代码就无法渲染DOM,渲染DOM的时候就无法执行js代码。如果按照这种同步方式执行,页面的渲染将会出现白屏甚至是报错,特别是遇到一些耗时比较长的网络请求或者js代码,因此在实际开发中一般是通过异步的方式解决。

什么是异步?js是一步一步执行代码的,遇到alert这种阻塞代码时,js将会停止往下执行直到阻塞代码执行完毕。异步就是将函数放在单独的异步队列中,不会产生阻塞,js可以继续往下执行,等到同步代码执行完毕后再执行异步队列中的函数。因此,js会先执行完同步代码,才会执行异步代码。异步函数之间,虽然都是异步,但是还是有相对的执行顺序。

异步函数的执行主要依靠事件循环来处理,本文重点探讨异步的分类(宏任务、微任务)、事件循环以及异步函数的执行顺序。

宏任务

宏任务,也可简单的说成是任务,在下一轮DOM渲染之后执行。常见的宏任务有:

微任务

微任务,在下一轮DOM渲染之前执行,微任务比宏任务更早执。常见的微任务有:

console.log('start');
// 微任务队列
Promise.resolve().then(() => {
    console.log('promise then');
});
queueMicrotask(() => {
    console.log('queueMicrotask');
});
console.log('end');

运行结果

start
end
promise then
queueMicrotask

事件循环

因为有异步操作的存在,所以出现了事件循环,如果都是同步操作,一行一行执行代码,事件循环也就失去了用武之地。在了解事件循环前,还需要补充js的执行过程:

js在执行代码时,遇到函数就会将其添加到调用栈中,每一帧都会存储当前函数的参数和局部变量,当一个函数执行完毕,则会从调用栈中弹出,直到栈被清空,那么程序也就执行完毕。在执行的过程中,需要的引用数据都是从堆中获取。

在实际开发中,往往是同步代码和异步代码都有。在js执行时,还是从第一行代码开始执行,遇到函数就将其添加到栈中,然后执行同步操作;如果遇到异步函数,则根据其类型,宏任务就添加到宏任务队列,微任务添加到微任务队列。直到同步代码执行完毕,则开始执行异步操作。

异步操作后于同步操作,异步操作内部也是分先后顺序的。总的来说:

微任务比宏任务先执行

console.log('start');
// 宏任务队列
setTimeout(() => {
    console.log('setTimeout');
});
// 微任务队列
Promise.resolve().then(() => {
    console.log('promise then');
});
console.log('end');
// 执行结果
start
end
promise then
setTimeout

微任务在下一轮DOM渲染前执行,宏任务在之后执行

let div = document.createElement('div');
div.innerHTML = 'hello world';
document.body.appendChild(div);
let divList = document.getElementByTagName('div');
console.log('同步任务 length ---', list.length);
console.log('start');
setTimeout(() => {
    console.log('setTimeout length ---', list.length);
    alert('宏任务 setTimeout 阻塞'); // 使用alert阻塞js执行
});
Promise.resolve().then(() => {
    console.log('promise then length ---', list.length);
    alert('微任务 promise then 阻塞);
});
console.log('end');

事件循环

event loop会持续监听是否有异步操作,如果有则添加到对应的队列中,等待执行。例如在宏任务中添加微任务,或者在微任务中添加宏任务,当前任务执行完后,可能还会有新的任务添加到事件循环中。

宏任务与微任务

总结

参考资料

到此这篇关于JavaScript事件循环的文章就介绍到这了,更多相关JS事件循环内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文