<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>$NextTick on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/nexttick/</link><description>Recent content in $NextTick on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sun, 15 Dec 2024 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/nexttick/index.xml" rel="self" type="application/rss+xml"/><item><title>$nextTick</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/vue/nexttick/</link><pubDate>Sat, 05 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/vue/nexttick/</guid><description>&lt;p&gt;&lt;code&gt;nextTick&lt;/code&gt; 是 Vue 的一个核心实现，&lt;code&gt;$nextTick&lt;/code&gt;方法将回调延迟到下次DOM更新循环之后执行。&lt;strong&gt;Vue 的 nextTick 其本质是对 JavaScript 执行原理 EventLoop 的一种应用。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;nextTick 的核心是利用了如 Promise 、MutationObserver、setImmediate、setTimeout的原生 JavaScript 方法来模拟对应的微/宏任务的实现，本质是为了利用 JavaScript 的这些异步回调任务队列来实现 Vue 框架中自己的异步回调队列&lt;/p&gt;
&lt;h2 id="前置知识---js事件循环"&gt;前置知识 - js事件循环&lt;/h2&gt;
&lt;h2 id="js-运行机制"&gt;JS 运行机制&lt;/h2&gt;
&lt;p&gt;JS 执行是单线程的，基于事件循环。事件循环大致分为以下步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;所有同步任务都在主线程上执行，形成一个执行栈。&lt;/li&gt;
&lt;li&gt;异步任务放进任务队列，异步任务分为宏任务和微任务&lt;/li&gt;
&lt;li&gt;执行栈所有同步任务执行完成，就会执行任务队列。对应的异步任务，结束等待状态，进入执行栈，开始执行。&lt;/li&gt;
&lt;li&gt;主线程不断重复上面的第三步。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;主线程的执行过程就是一个 tick，而所有的异步结果都是通过 “任务队列” 来调度。 消息队列中存放的是一个个的任务（task）。 task 分为两大类，分别是 macro task 和 micro task，并且每个 macro task(宏任务) 结束后，都要清空所有的 micro task(微任务)。&lt;/p&gt;
&lt;p&gt;如图所示&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;macroTask&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;of&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;macroTaskQueue&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 执行宏任务
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;handleMacroTask&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 执行所有微任务
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;microTask&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;of&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;microTaskQueue&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;handleMicroTask&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;microTask&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;宏任务&lt;/code&gt;： script、setTimeout、setInterval、Node中的setImmediate 等&lt;br&gt;
&lt;code&gt;微任务&lt;/code&gt;： Promise.then、MutationObserver、Node 中的 Process.nextTick等&lt;/p&gt;</description></item></channel></rss>