<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Boundarylesstacks</title>
        <link>https://boundarylesstacks.com</link>
        <description>I am RZ, web frontend developer</description>
        <lastBuildDate>Sun, 10 May 2026 09:14:48 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Boundarylesstacks</title>
            <url>https://boundarylesstacks.com/images/favicons/favicon-32x32.png</url>
            <link>https://boundarylesstacks.com</link>
        </image>
        <copyright>&amp;copy;2026 RZ Huang. All rights reserved.</copyright>
        <atom:link href="https://boundarylesstacks.com/api/feed.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[The `finally` behavior in `try…catch` of JavaScript]]></title>
            <link>https://boundarylesstacks.com/post/2025-the-finally-behavior-in-try-catch-of-javascript/</link>
            <guid>https://boundarylesstacks.com/post/2025-the-finally-behavior-in-try-catch-of-javascript/</guid>
            <pubDate>Sat, 19 Apr 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[finally behavior in JavaScript]]></description>
            <content:encoded><![CDATA[<h2 id="來源">來源</h2>
<p><img src="x-source.png" alt="source-from-x"></p>
<ul>
<li><a href="https://x.com/aidenybai/status/1898043212238901444">https://x.com/aidenybai/status/1898043212238901444</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch#the_finally_block">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try…catch#the_finally_block</a></li>
</ul>
<p>原文是希望藉由這樣的寫法，不 block 到 response（<code>return data</code>）的情況下，在 <code>finally</code> block 做最後的 <code>cleanup</code>，但是適得其反，為什麼呢？</p>
<p><img src="example-w-o-await.png" alt="example-w-o-await">
他自己也注意到了，<code>finally</code> block 會先執行，才回 return <code>try</code> block 的值，怎麼會這樣？</p>
<h2 id="來看看文件怎麼寫">來看看文件怎麼寫</h2>
<p>根據 MDN 的 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch#the_finally_block">The finally block</a> 段落，寫道 <code>finally</code> block 執行的時機點有 3 個：</p>
<blockquote>
<ul>
<li>Immediately after the <code>try</code> block finishes execution normally (and no exceptions were thrown);</li>
<li>Immediately after the <code>catch</code> block finishes execution normally;</li>
<li>Immediately before the execution of a control-flow statement (<code>return</code>, <code>throw</code>, <code>break</code>, <code>continue</code>) in the <code>try</code> block or <code>catch</code> block that would exit the block.</li>
</ul>
</blockquote>
<p>前面兩點相信很好懂，重點在第三點：「<code>finally</code> 會在執行任何 control-flow statement 之前就會馬上執行，包括在 <code>try</code> block 和 <code>catch</code> block 當中，可能會導致離開 block 的 control-flow statement」</p>
<h3 id="what-is-control-flow-statement">What is control-flow statement?</h3>
<p>根據上面原文來舉例，就會是 <code>try</code> block 裡面的 <code>return</code> ，因此 <code>finally</code> block 的 <code>await cleanup()</code> 會先執行，才執行 <code>try</code> block 的 return</p>
<p>舉個例子：</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="js"><code><span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> fn</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  try</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"try"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#F97583">    return</span><span style="color:#9ECBFF"> "true"</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">  } </span><span style="color:#F97583">finally</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"finally"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">  }</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">const</span><span style="color:#79B8FF"> data</span><span style="color:#F97583"> =</span><span style="color:#B392F0"> fn</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"data: "</span><span style="color:#E1E4E8">, data);</span></span></code></pre>
<p>print log 的順序會是：</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="plaintext"><code><span class="line"><span>try</span></span>
<span class="line"><span>finally</span></span>
<span class="line"><span>true</span></span></code></pre>
<p>可以看到 <code>try</code> block 的return 最後才被執行</p>
<p>如果把上面例子的 <code>return “true”</code> 改成 <code>throw “123”</code>：</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="js"><code><span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> fn</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  try</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"try"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#F97583">    throw</span><span style="color:#9ECBFF"> "123"</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">  } </span><span style="color:#F97583">finally</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"finally"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">  }</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">const</span><span style="color:#79B8FF"> data</span><span style="color:#F97583"> =</span><span style="color:#B392F0"> fn</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"data: "</span><span style="color:#E1E4E8">, data);</span></span></code></pre>
<p>print log 的順序會是：</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="plaintext"><code><span class="line"><span>try</span></span>
<span class="line"><span>finally</span></span>
<span class="line"><span>Error: 123</span></span></code></pre>
<p>結果差不多，可以看到 throw 錯誤之前，<code>finally</code> block 會先被執行</p>
<p>回到原文中的例子：</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="js"><code><span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> cleanup</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span></span>
<span class="line"><span style="color:#F97583">  new</span><span style="color:#79B8FF"> Promise</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">resolve</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"resolve"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#B392F0">    resolve</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">  });</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> fn</span><span style="color:#F97583"> =</span><span style="color:#F97583"> async</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  try</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"try"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#F97583">    return</span><span style="color:#9ECBFF"> "true"</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">  } </span><span style="color:#F97583">finally</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"finally"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#F97583">    await</span><span style="color:#B392F0"> cleanup</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">  }</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">fn</span><span style="color:#E1E4E8">().</span><span style="color:#B392F0">then</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">data</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">  console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"data: "</span><span style="color:#E1E4E8">, data);</span></span>
<span class="line"><span style="color:#E1E4E8">});</span></span></code></pre>
<p>print 出 log 的順序則是：</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="plaintext"><code><span class="line"><span>try</span></span>
<span class="line"><span>finally</span></span>
<span class="line"><span>resolve</span></span>
<span class="line"><span>data:  true</span></span></code></pre>
<p>很明顯可以看到 <code>finally</code> block 的 promise 執行完之後，才執行 <code>return “true”</code></p>
<h2 id="可以用什麼替代原文作者的寫法">可以用什麼替代原文作者的寫法？</h2>
<h3 id="只在-finally-block-寫-control-flow-statementnot-perfect">只在 <code>finally</code> block 寫 control-flow statement（not perfect）</h3>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="plaintext"><code><span class="line"><span>const fn = async () => {</span></span>
<span class="line"><span>  try {</span></span>
<span class="line"><span>    console.log("try");</span></span>
<span class="line"><span>  } finally {</span></span>
<span class="line"><span>    cleanup();</span></span>
<span class="line"><span>    return "true"</span></span>
<span class="line"><span>  }</span></span>
<span class="line"><span>};</span></span></code></pre>
<p>有網友提供這樣的寫法，可以在 <code>cleanup</code> 後接著 return value，一石二鳥。不過如果今天 <code>try</code> block 裡面需要 await data 或做其它事，必須還得在外面 assign 一個變數，才能讓 <code>finally</code> block return data 出去，像這樣：</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="js"><code><span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> fn</span><span style="color:#F97583"> =</span><span style="color:#F97583"> async</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  let</span><span style="color:#E1E4E8"> data;</span></span>
<span class="line"><span style="color:#F97583">  try</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"try"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">    data </span><span style="color:#F97583">=</span><span style="color:#F97583"> await</span><span style="color:#B392F0"> doSomething</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">  } </span><span style="color:#F97583">finally</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#B392F0">    cleanup</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#F97583">    return</span><span style="color:#E1E4E8"> data;</span></span>
<span class="line"><span style="color:#E1E4E8">  }</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code></pre>
<p>另外就是，假如希望 <code>catch</code> block 能 throw error 或 return error 到外面去，讓外部知道有 error，這種寫法可能就不適合了。</p>
<h3 id="老老實實地在-trycatch-執行完的下一行做-cleanup">老老實實地在 <code>try…catch</code> 執行完的下一行做 cleanup</h3>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="js"><code><span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> cleanup</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span></span>
<span class="line"><span style="color:#F97583">  new</span><span style="color:#79B8FF"> Promise</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">resolve</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"resolve"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#B392F0">    resolve</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">  });</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> fn</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  try</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"try"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#F97583">    return</span><span style="color:#9ECBFF"> "true"</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">  } </span><span style="color:#F97583">catch</span><span style="color:#E1E4E8"> (error) {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"error: "</span><span style="color:#E1E4E8">, error);</span></span>
<span class="line"><span style="color:#E1E4E8">  }</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">fn</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#B392F0">cleaup</span><span style="color:#E1E4E8">();</span></span></code></pre>
<p>夠粗暴，且簡單與直覺。</p>
<h3 id="用-finally">用 <code>.finally()</code></h3>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="js"><code><span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> cleanup</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span></span>
<span class="line"><span style="color:#F97583">  new</span><span style="color:#79B8FF"> Promise</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">resolve</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"resolve"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#B392F0">    resolve</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">  });</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> fn</span><span style="color:#F97583"> =</span><span style="color:#F97583"> async</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  try</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"try"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#F97583">    return</span><span style="color:#9ECBFF"> "true"</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">  } </span><span style="color:#F97583">catch</span><span style="color:#E1E4E8"> (error) {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"error: "</span><span style="color:#E1E4E8">, error);</span></span>
<span class="line"><span style="color:#E1E4E8">  }</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">fn</span><span style="color:#E1E4E8">()</span></span>
<span class="line"><span style="color:#E1E4E8">  .</span><span style="color:#B392F0">then</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">data</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"data: "</span><span style="color:#E1E4E8">, data);</span></span>
<span class="line"><span style="color:#E1E4E8">  })</span></span>
<span class="line"><span style="color:#E1E4E8">  .</span><span style="color:#B392F0">finally</span><span style="color:#E1E4E8">(() </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"finally"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#B392F0">    cleanup</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">  });</span></span></code></pre>
<p>可以用 <code>.finally()</code> 的方式來做取代，這種方式基本上可以確保 return 值之後，才會進到 <code>.finally()</code>，缺點就是寫起來會變得又臭又長?</p>
<p>要寫得比較完整的話，可以再加上 <code>.catch()</code></p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="js"><code><span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> cleanup</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span></span>
<span class="line"><span style="color:#F97583">  new</span><span style="color:#79B8FF"> Promise</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">resolve</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"resolve"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#B392F0">    resolve</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">  });</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> fn</span><span style="color:#F97583"> =</span><span style="color:#F97583"> async</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  try</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"try"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#F97583">    return</span><span style="color:#9ECBFF"> "true"</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">  } </span><span style="color:#F97583">catch</span><span style="color:#E1E4E8"> (error) {</span></span>
<span class="line"><span style="color:#F97583">    throw</span><span style="color:#E1E4E8"> error;</span></span>
<span class="line"><span style="color:#E1E4E8">  }</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">fn</span><span style="color:#E1E4E8">()</span></span>
<span class="line"><span style="color:#E1E4E8">  .</span><span style="color:#B392F0">then</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">data</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"data: "</span><span style="color:#E1E4E8">, data);</span></span>
<span class="line"><span style="color:#E1E4E8">  })</span></span>
<span class="line"><span style="color:#E1E4E8">  .</span><span style="color:#B392F0">catch</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">error</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"error: "</span><span style="color:#E1E4E8">, error);</span></span>
<span class="line"><span style="color:#E1E4E8">  })</span></span>
<span class="line"><span style="color:#E1E4E8">  .</span><span style="color:#B392F0">finally</span><span style="color:#E1E4E8">(() </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"finally"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#B392F0">    cleanup</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">  });</span></span></code></pre>
<h3 id="另一個比較常見的寫法用-promise-包著">另一個比較常見的寫法：用 <code>Promise</code> 包著</h3>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="js"><code><span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> cleanup</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span></span>
<span class="line"><span style="color:#F97583">  new</span><span style="color:#79B8FF"> Promise</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">resolve</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"resolve"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#B392F0">    resolve</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">  });</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> fn</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#F97583"> new</span><span style="color:#79B8FF"> Promise</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">resolve</span><span style="color:#E1E4E8">, </span><span style="color:#FFAB70">reject</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">    try</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">      console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"try"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#B392F0">      resolve</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"true"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">    } </span><span style="color:#F97583">catch</span><span style="color:#E1E4E8"> (error) {</span></span>
<span class="line"><span style="color:#B392F0">      reject</span><span style="color:#E1E4E8">(error);</span></span>
<span class="line"><span style="color:#E1E4E8">    }</span></span>
<span class="line"><span style="color:#E1E4E8">  });</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0">fn</span><span style="color:#E1E4E8">()</span></span>
<span class="line"><span style="color:#E1E4E8">  .</span><span style="color:#B392F0">then</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">data</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"data: "</span><span style="color:#E1E4E8">, data);</span></span>
<span class="line"><span style="color:#E1E4E8">  })</span></span>
<span class="line"><span style="color:#E1E4E8">  .</span><span style="color:#B392F0">catch</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">error</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"error: "</span><span style="color:#E1E4E8">, error);</span></span>
<span class="line"><span style="color:#E1E4E8">  })</span></span>
<span class="line"><span style="color:#E1E4E8">  .</span><span style="color:#B392F0">finally</span><span style="color:#E1E4E8">(() </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"finally"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#B392F0">    cleanup</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">  });</span></span></code></pre>
<h2 id="千萬別這麼做">千萬別這麼做</h2>
<p>看到原文串有人舉一個例子表示千萬別這麼做，否則會討厭你自己</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="js"><code><span class="line"><span style="color:#F97583">function</span><span style="color:#B392F0"> tryMe</span><span style="color:#E1E4E8">() {</span></span>
<span class="line"><span style="color:#E1E4E8">  console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"1. start!"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#F97583">  try</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">    return</span><span style="color:#9ECBFF"> "2. return from try"</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">  } </span><span style="color:#F97583">catch</span><span style="color:#E1E4E8"> (error) {</span></span>
<span class="line"><span style="color:#F97583">    return</span><span style="color:#9ECBFF"> "3. return from catch"</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">  } </span><span style="color:#F97583">finally</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">    return</span><span style="color:#9ECBFF"> "4. return from finally"</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">  }</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8">console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#B392F0">tryMe</span><span style="color:#E1E4E8">());</span></span></code></pre>
<p>log 的順序將會是：</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="plaintext"><code><span class="line"><span>1. start!</span></span>
<span class="line"><span>2. return from finally</span></span></code></pre>
<p>沒錯，直接略過 <code>try</code> 跟 <code>catch</code> block</p>
<p>即使你今天在 <code>try</code> block 丟出一個錯誤，也不會 return <code>catch</code> block 的字串</p>
<h2 id="總結">總結</h2>
<p><code>finally</code> block 目前看起來存在著些違反直覺的機制，可能會在無意中寫出令你驚喜的情況，看起來能不用就不用，似乎也沒有非得使用的必要。若仍要使用，請絕對要小心服用，並有意識地在知道 <code>finally</code> block 的機制下去做使用。</p>
<h3 id="網友分享另一個變形題">網友分享另一個變形題</h3>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="js"><code><span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> xit</span><span style="color:#F97583"> =</span><span style="color:#F97583"> async</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#B392F0"> zit</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"second"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#F97583">    return</span><span style="color:#9ECBFF"> "fourth"</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">  };</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">  try</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">    await</span><span style="color:#F97583"> new</span><span style="color:#79B8FF"> Promise</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">resolve</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#B392F0"> setTimeout</span><span style="color:#E1E4E8">(resolve), </span><span style="color:#79B8FF">100</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"first"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#F97583">    return</span><span style="color:#B392F0"> zit</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">  } </span><span style="color:#F97583">finally</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"third"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">  }</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8">(</span><span style="color:#F97583">async</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#79B8FF"> data</span><span style="color:#F97583"> =</span><span style="color:#F97583"> await</span><span style="color:#B392F0"> xit</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">  console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"data: "</span><span style="color:#E1E4E8">, data);</span></span>
<span class="line"><span style="color:#E1E4E8">})();</span></span></code></pre>
<p>猜猜答案會是什麼？</p>
<details>
  <summary>Answer</summary>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="plaintext"><code><span class="line"><span>first</span></span>
<span class="line"><span>second</span></span>
<span class="line"><span>third</span></span>
<span class="line"><span>data:  fourth</span></span></code></pre>
<p>(<a href="https://x.com/berliangor/status/1898252789639520282">ref</a>)</p>
</details>]]></content:encoded>
            <author>94rzhuang@email.com (RZ Huang)</author>
        </item>
        <item>
            <title><![CDATA[First post]]></title>
            <link>https://boundarylesstacks.com/post/2025-test-first-post/</link>
            <guid>https://boundarylesstacks.com/post/2025-test-first-post/</guid>
            <pubDate>Wed, 01 Jan 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Test]]></description>
            <content:encoded><![CDATA[<p>Hello everyone, this is the first post of the blog</p>]]></content:encoded>
            <author>94rzhuang@email.com (RZ Huang)</author>
        </item>
    </channel>
</rss>