Javascript是一种单线程开发语言。了解Javascript的运行机制是日常编码的必备技能。为什么是单线程的?JavaScript的主要目的是与用户交互和操作DOM。这就决定了它只能是单线程的,否则会带来非常复杂的同步问题。假设:如果JavaScript支持多线程,一个线程向某个DOM节点添加内容,另一个线程删除这个节点,浏览器应该以哪个线程为基础?单线程的缺点单线程意味着线程很容易等待资源,cpu空闲,其他任务一直在等待。什么是EventLoop(事件循环)为了协调事件、用户交互、脚本、UI渲染和网络处理,防止主线程阻塞。因此,Javascript设计者将所有任务分为两种,一种是同步任务,一种是异步任务。同步任务是指在主线程上排队等待执行的任务。任务。同步任务都在主线程上执行,形成一个执行栈。栈每次执行时执行的代码是一个宏任务。异步任务是指不进入主线程而是进入任务队列的任务。只要指定了回调函数,这些事件就会在发生时(比如鼠标点击……等)进入“任务队列”。一旦执行栈中的所有同步任务都执行完毕,系统就会读取“任务队列”。任务队列是一个先进先出的数据结构,前面的事件先被主线程读取。“主线程”从“任务队列”中读取事件。这个过程是连续的,所以整个运行机制也称为EventLoop(事件循环)。宏任务和微任务是基于规范的:每个任务都有一个任务源,来自同一个任务源的任务必须放在同一个任务队列中,不同源的任务加入不同的队列,所以有宏任务(宏)任务和微任务(micro)任务。为了让JS内部(宏)任务和DOM任务能够有序执行,浏览器会在一个任务执行结束后,下一个(宏)任务开始执行前,重新渲染页面,每执行一次macro执行任务后,会检查是否有microtask;如果有,则执行微任务,直到微任务队列被清除。如果在微任务执行过程中有新的微任务加入到微任务队列中,新的微任务会被加入到队列的尾部。稍后会被执行。根据以上总结流程:附(宏/微任务列表):宏任务(macro)任务主要包括:script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、postMessage、MessageChannel、setImmediate(Node.js环境)微任务(micro)任务主要包括:Promise.then、MutaionObserver、process.nextTick(Node.js环境)requestAnimationFrame既不是宏任务也不是微任务。目前宏任务和微任务在各个浏览器中的执行方式存在差异,最后提出Promise进行微任务实例分析setTimeout(function(){console.log('1');});newPromise(function(resolve){console.log('2');resolve();}).then(function(){console.log('3');});控制台日志('4');以上案例会输出2431结果分析:JavaScript执行主线程任务:输出24附:Promise构造函数内部是一个同步任务执行微任务队列:输入3第一个宏任务结束,进入setTimeout回调:输出1完继续更新,来Github点击?栏返回首页
