9.1任务分类9.1.1广义分类从广义上看,任务主要分为同步任务和异步任务两种。同步任务是在主线程上排队等待执行的任务,只有在上一个任务完成后才能执行下一个任务。异步任务不进入主线程,而是进入“任务队列”的任务,只有当“任务队列”通知主进程有异步任务可以执行时,任务才会进入主线程执行。(注:异步任务解决性能问题)下面展开:为什么会有异步任务?因为js是单线程的,如果只有同步任务,所有任务都在单线程中执行,所以一次任务只能执行一个,而其他任务都处于等待状态,导致下一个任务等待许久。这个问题可以通过异步任务很好的解决。9.1.2精确分类除了广义上的同步任务和异步任务的分类外,其实还有更精确的分类:宏任务和微任务。宏任务宏任务主要是指任务队列中的这些任务,主要包括以下几类:(1)整体脚本代码(2)setTimeout(3)setInterval(4)setImmediate(Nodeunique)(5)I/OMicrotaskAmicrotask是一个需要异步执行的函数。执行时机在main函数执行之后,当前macrotask结束之前。主要包括以下几类:(注:microtasks解决实时性问题)(1)process.nextTick(节点唯一)在下一个时间点向队列添加回调;(2)MutationObserver使用MutationObserver监控某个DOM节点。当DOM节点发生变化时,会生成一个DOM变化记录的微任务。(3)Promise及基于Promise开发的其他技术(注:调用Prommise.resolve()或Promise.reject()时也会产生微任务)展开:为什么我们需要微任务?它解决了什么问题?如果没有微任务,以相同的优先级顺序执行所有操作,会导致一些高优先级的任务出现实时性问题,因此会出现微任务。通过将实时性要求较高的任务放入微任务队列中,保证了高优先级任务的实时性要求。9.2事件循环流程JS使用单线程的“事件循环(EventLoop)”来处理多个任务的执行。下面从两个角度来解释整个过程。9.2.1同步和异步视角从同步和异步任务的角度来看,整个事件循环过程可以分为以下几个步骤:同步和异步任务进入不同的执行地点,同步进入主线程,异步进入EventTable和注册一个函数;当指定的事情完成后,EventTable会将这个函数移入EventQueue;当主线程的任务完成,为空时,会去EventQueue中读取相应的函数,进入主线程执行;上面的过程会不断重复,这就是Changshu的EventLoop(事件循环)。cmd-markdown-logo注:本图来自网络9.2.2从宏任务和微任务的角度来看从宏任务和微任务的角度来看,整个事件循环机制可以分为以下几个步骤:获取一个macrotask开始执行,执行时首先创建一个microtask队列,遇到microtask就将microtask放入microtask队列;然后获取microtask队列中的所有microtasks,然后依次执行(注:执行microtask时产生的microtasks任务会被放到microtask队列的尾部,在本次循环中执行完毕)并且该过程将循环执行。9.3实战事件循环的核心内容是需要明确区分任务类型,只要把任务类型划分好依次执行,一段代码演示如下输出内容。console.log('start');setTimeout(function(){console.log('setTimeout1');constpromise2=newPromise((resolve,reject)=>{console.log('promise2');resolve();});promise2.then(()=>{console.log('then2');constpromise3=newPromise(resolve=>{console.log('promise3');resolve();});promise3.then(()=>{console.log('then3');});});},1000);setTimeout(function(){console.log('setTimeout2');constpromise4=newPromise((resolve,reject)=>{console.log('promise4');resolve();});promise4.then(()=>{console.log('then4');});},1000);constpromise1=newPromise(resolve=>{console.log('promise1');resolve();});promise1.then(()=>{console.log('then1');});console.log('end');只要了解整个事件循环机制,就很容易得到答案,答案如下:startpromise1endthen1setTimeout1promise2then2promise3then3setTimeout2promise4then4本文转载自微信公众号“风筝”,可以通过以下二维码关注。转载本文请联系风筝持有人公众号。
