一、介绍
在JavaScript中所有任务都是单线程的,也就是说一次只能做一件事。 事件循环是 JavaScript 运行时的一个核心概念,它使得 JavaScript 能够处理异步操作。在 JavaScript 中,事件循环主要与单线程的执行环境相关,确保在执行同步代码的同时,能够处理异步任务,如网络请求、定时事件(如 setTimeout 或 setInterval)、文件读写等
二、工作原理
事件循环的工作原理
调用栈:
JavaScript 代码执行时,所有同步任务都在调用栈中执行。
当一个函数被调用时,它被添加到栈顶,执行完成后从栈顶移除。
事件队列:
异步任务(如定时器等)完成后,它们的回调函数不会立即执行,而是被放入事件队列中等待。
事件队列按照先进先出的原则管理回调函数。
事件循环(Event Loop):
事件循环检查调用栈是否为空。
如果调用栈为空,事件循环将从事件队列中取出第一个任务,放入调用栈中执行。
这个过程会不断重复,即循环检查调用栈和事件队列这个过程就叫做事件循环
三、同步与异步
同步任务:
同步操作是阻塞的,意味着在操作完成之前,它会阻塞代码的执行。也就是说js是单线程的,按照顺序执行 只有前面的任务执行完了 才会执行后面调用者必须等待操作完成才能继续执行后续代码 。
异步任务
宏任务(Macro Tasks):
包括 setTimeout、setInterval、setImmediate、I/O、UI 渲染等。
微任务(Micro Tasks):
包括 Promise .then 、MutationObserver 等。
事件循环在每次循环时,会先处理所有微任务,然后再处理下一个宏任务。这意味着微任务的回调函数会优先于下一个宏任务执行。
四、示例
在下面这段代码中可以看出微任务和宏任务的执行顺序
执行到13行的时候有个setTimeout定时器 setTimeout在异步任务里面是宏任务 这里不会立即执行先放进宏任务队列里面 然后到16行有个Promise函数里面有两个.then微任务就把这两个任务先放进微任务里面 接着就会把整个js的任务执行一遍 如果外面的同步执行完了 就会先去微任务里面找 也就是先打印出17行和19行 这里是先进先出的顺序 微任务执行完了 就去宏任务找 打印出14行 这个找任务的过程就叫做事件循环