手机免费建站教程,赤坎手机网站建设,wordpress阿里百秀5.4,买一个域名多少钱事件循环(Event Loop)#xff0c;是每个JS开发者都会接触到的概念#xff0c;但是刚接触时可能会存在各种疑惑。众所周知#xff0c;JS是单线程的#xff0c;即同一时间只能运行一个任务。一般情况下这不会引发问题#xff0c;但是如果我们有一个耗时较多的任务#xff0…事件循环(Event Loop)是每个JS开发者都会接触到的概念但是刚接触时可能会存在各种疑惑。众所周知JS是单线程的即同一时间只能运行一个任务。一般情况下这不会引发问题但是如果我们有一个耗时较多的任务我们必须等该任务执行完毕才能进入下一个任务然而等待的这段时间常常让我们无法忍受因为我们这段时间什么都不能做包括页面也是锁死状态。好在时代在进步浏览器向我们提供了JS引擎不具备的特性Web API。Web API包括DOM API、定时器、HTTP请求等特性可以帮助我们实现异步、非阻塞的行为。我们可以通过异步执行任务的方法来解决单线程的弊端事件循环为此而生。提问QAQ为什么JavaScript是单线程的多个线程表示您可以同时独立执行程序的多个部分。确定一种语言是单线程还是多线程的最简单方法是看它拥有有多少个调用堆栈。JS 只有一个所以它是单线程语言。将JS设计为单线程是由其用途运行环境等因素决定的作为浏览器脚本语言JS的主要用途是与用户互动以及操作DOM。这决定了它只能是单线程否则会带来很复杂的同步问题。同时单线程执行效率高。1. Event Loop旧印象大家熟悉的关于事件循环的机制说法大概是主进程执行完了之后每次从任务队列里取一个任务执行。如图所示所有的任务分为同步任务和异步任务同步任务直接进入任务队列--主程序执行异步任务则会挂起等待其有返回值时进入任务队列从而被主程序执行。异步任务会通过任务队列的机制(先进先出的机制)来进行协调。具体如图所示同步和异步任务分别进入不同的执行环境同步的进入主线程即主执行栈异步的进入任务队列。主线程内的任务执行完毕为空会去任务队列读取对应的任务推入主线程执行。 上述过程的不断重复就是我们所熟悉的Event Loop (事件循环)。但是promise出现之后这个说法就不太准确了。2. Event Loop 后印象2.1 理论这里首先用一张图展示JavaScript的事件循环直接看这张图可能黑人问号已经出现在同学的脑海。。。这里将task分为两大类分别是macroTask(宏任务)和microTask(微任务).一次事件循环先运行macroTask队列中的一个然后运行microTask队列中的所有任务。接着开始下一次循环(只是针对macroTask和microTask一次完整的事件循环会比这个复杂的多)。那什么是macroTask什么是microTask呢JavaScript引擎把我们的所有任务分门别类一部分归为macroTask另外一部分归为microTack下面是类别划分macroTask:setTimeoutsetIntervalsetImmediaterequestAnimationFrameI/OUI renderingmicroTask:process.nextTickPromiseObject.observeMutationObserver我们所熟悉的定时器就属于macroTask仅仅了解macroTask的机制还是不够的。为直观感受两种队列的区别下面上代码进行实践感知。2.2 实践以setTimeout、process.nextTick、promise为例直观感受下两种任务队列的运行方式。console.log(main1);process.nextTick(function() {console.log(process.nextTick1);});setTimeout(function() {console.log(setTimeout);process.nextTick(function() {console.log(process.nextTick2);});}, 0);new Promise(function(resolve, reject) {console.log(promise);resolve();}).then(function() {console.log(promise then);});console.log(main2);别着急看答案先以上面的理论自己想想运行结果会是啥最终结果是这样的main1promisemain2process.nextTick1promise then// 第二次事件循环setTimeoutprocess.nextTick2process.nextTick 和 promise then在 setTimeout 前面输出已经证明了macroTask和microTask的执行顺序。但是有一点必须要指出的是。上面的图容易给人一个错觉就是主进程的代码执行之后会先调用macroTask再调用microTask这样在第一个循环里一定是macroTask在前microTask在后。但是最终的实践证明在第一个循环里process.nextTick1和promise then这两个microTask是在setTimeout这个macroTask里之前输出的这是因为Promises/A规范规定主进程的代码也属于macroTask。主进程这个macroTask(也就是main1、promise和main2)执行完了自然会去执行process.nextTick1和promise then这两个microTask。这是第一个循环。之后的setTimeout和process.nextTick2属于第二个循环别看上面那段代码好像特别绕把原理弄清楚了都一样 ~requestAnimationFrame、Object.observe(已废弃) 和 MutationObserver这三个任务的运行机制大家可以从上面看到不同的只是具体用法不同。重点说下UI rendering。在HTML规范event-loop-processing-model里叙述了一次事件循环的处理过程在处理了macroTask和microTask之后会进行一次Update the rendering其中细节比较多总的来说会进行一次UI的重新渲染。3. 小结总而言之记住一次事件循环先运行macroTask队列中的一个然后运行microTask队列中的所有任务。接着开始下一次循环。参考文献JavaScript Event Loop相关原理解析深入理解事件循环机制JavaScript运行机制以上就是深入分析JavaScript 事件循环(Event Loop)的详细内容更多关于JavaScript 事件循环(Event Loop)的资料请关注聚米学院其它相关文章