前言JavaScript是一种单线程的弱类型语言,但是我们在开发中经常会遇到一些需要异步或者等待的处理操作。类似于ajax,或者ES6中新增的promise操作,用来处理一些回调函数等。概念在JavaScript代码执行过程中,可以分为同步队列和异步队列。同步任务类似于我们常说的立即执行功能。它们可以不用等待直接执行,可以直接在主线程中执行,类似于普通的函数调用。异步队列是异步执行函数,类似于ajax请求。我们在启动过程中会进入一个异步队列。当加载到任务中时,我们需要等待才能处理返回值。拿下面这段代码举个栗子,我们可以先了解一下事件循环机制的一些基本原理console.log('1');setTimeout(function(){console.log('4');},0);Promise.resolve().then(function(){console.log('2');}).then(function(){console.log('3');});console.log('5');我们把代码打印到控制台,输出结果是:1,5,2,3,4我们知道在JavaScript中,类似于定时器,ES6加入的promises都是异步函数,回到我们上面说的概念当中上面提到的队列,不难得出1和5是同步执行队列。同步队列中的代码执行完后,再执行异步队列中的代码。TIP在解析异步队列的promise和timer时,我们发现timersetTimeout是在promise之后执行的。这里介绍一下JavaScript规范中宏任务(MacroTask)和微任务(MicroTask)的概念。宏任务包括:script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、setImmediate(Node.js环境)微任务:Promise、MutaionObserver、process.nextTick(Node.js环境)然后返回上面这个时候我们知道,在JavaScript中,当有异步队列时,先执行microtask,再执行macrotask。再次,如果异步队列中存在异步队列,我们??需要做什么?console.log(1);setTimeout(function(){console.log(5);},10);newPromise(resolve=>{console.log(2);resolve();setTimeout(()=>console.log(3),10);}).then(function(){console.log(4);})console.log(6);到控制台执行代码,打印顺序为:1、2、6、4、5、3,与例1中的promise不同,打印2先于6执行。由此可知,在执行过程中执行resolve或rejected之前执行新的Promise。这些代码都是同步队列中的代码。看4、5、3的执行顺序,执行完微任务promise执行回调resolve后,打印结果中会立即执行相应的then。定时器5会先执行---->宏任务属于微任务promise定时器3和定时器5的宏任务添加在promise微任务队列之后。在promise执行完then回调完成后,将promise中的宏任务添加到队列中。所以定时器5之后的执行总结在JavaScript中,宏任务包括:script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、setImmediate(Node.js环境)微任务:Promise、MutaionObserver、process.nextTick(Node.js环境);在执行过程中,同步代码优先于其他任务队列中的代码。timers、promises等任务在执行时会先加入到队列中。同步代码执行后,会根据宏任务和微任务进行分类,先执行微任务队列,再执行宏任务队列。文章个人博客地址:JavaScript事件循环机制
