{
    "version": "https://jsonfeed.org/version/1",
    "title": "Boundarylesstacks",
    "home_page_url": "https://boundarylesstacks.com",
    "feed_url": "https://boundarylesstacks.com/api/feed.json",
    "description": "I am RZ, web frontend developer",
    "icon": "https://boundarylesstacks.com/images/favicons/favicon-32x32.png",
    "author": {
        "name": "RZ Huang",
        "url": "https://boundarylesstacks.com/about/"
    },
    "items": [
        {
            "id": "https://boundarylesstacks.com/post/2025-the-finally-behavior-in-try-catch-of-javascript/",
            "content_html": "<h2 id=\"來源\">來源</h2>\n<p><img src=\"x-source.png\" alt=\"source-from-x\"></p>\n<ul>\n<li><a href=\"https://x.com/aidenybai/status/1898043212238901444\">https://x.com/aidenybai/status/1898043212238901444</a></li>\n<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>\n</ul>\n<p>原文是希望藉由這樣的寫法，不 block 到 response（<code>return data</code>）的情況下，在 <code>finally</code> block 做最後的 <code>cleanup</code>，但是適得其反，為什麼呢？</p>\n<p><img src=\"example-w-o-await.png\" alt=\"example-w-o-await\">\n他自己也注意到了，<code>finally</code> block 會先執行，才回 return <code>try</code> block 的值，怎麼會這樣？</p>\n<h2 id=\"來看看文件怎麼寫\">來看看文件怎麼寫</h2>\n<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>\n<blockquote>\n<ul>\n<li>Immediately after the <code>try</code> block finishes execution normally (and no exceptions were thrown);</li>\n<li>Immediately after the <code>catch</code> block finishes execution normally;</li>\n<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>\n</ul>\n</blockquote>\n<p>前面兩點相信很好懂，重點在第三點：「<code>finally</code> 會在執行任何 control-flow statement 之前就會馬上執行，包括在 <code>try</code> block 和 <code>catch</code> block 當中，可能會導致離開 block 的 control-flow statement」</p>\n<h3 id=\"what-is-control-flow-statement\">What is control-flow statement?</h3>\n<p>根據上面原文來舉例，就會是 <code>try</code> block 裡面的 <code>return</code> ，因此 <code>finally</code> block 的 <code>await cleanup()</code> 會先執行，才執行 <code>try</code> block 的 return</p>\n<p>舉個例子：</p>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">  try</span><span style=\"color:#E1E4E8\"> {</span></span>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">    return</span><span style=\"color:#9ECBFF\"> \"true\"</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  } </span><span style=\"color:#F97583\">finally</span><span style=\"color:#E1E4E8\"> {</span></span>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">};</span></span>\n<span class=\"line\"></span>\n<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>\n<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>\n<p>print log 的順序會是：</p>\n<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>\n<span class=\"line\"><span>finally</span></span>\n<span class=\"line\"><span>true</span></span></code></pre>\n<p>可以看到 <code>try</code> block 的return 最後才被執行</p>\n<p>如果把上面例子的 <code>return “true”</code> 改成 <code>throw “123”</code>：</p>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">  try</span><span style=\"color:#E1E4E8\"> {</span></span>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">    throw</span><span style=\"color:#9ECBFF\"> \"123\"</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  } </span><span style=\"color:#F97583\">finally</span><span style=\"color:#E1E4E8\"> {</span></span>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">};</span></span>\n<span class=\"line\"></span>\n<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>\n<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>\n<p>print log 的順序會是：</p>\n<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>\n<span class=\"line\"><span>finally</span></span>\n<span class=\"line\"><span>Error: 123</span></span></code></pre>\n<p>結果差不多，可以看到 throw 錯誤之前，<code>finally</code> block 會先被執行</p>\n<p>回到原文中的例子：</p>\n<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>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#B392F0\">    resolve</span><span style=\"color:#E1E4E8\">();</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  });</span></span>\n<span class=\"line\"></span>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">  try</span><span style=\"color:#E1E4E8\"> {</span></span>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">    return</span><span style=\"color:#9ECBFF\"> \"true\"</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  } </span><span style=\"color:#F97583\">finally</span><span style=\"color:#E1E4E8\"> {</span></span>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">    await</span><span style=\"color:#B392F0\"> cleanup</span><span style=\"color:#E1E4E8\">();</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">};</span></span>\n<span class=\"line\"></span>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">});</span></span></code></pre>\n<p>print 出 log 的順序則是：</p>\n<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>\n<span class=\"line\"><span>finally</span></span>\n<span class=\"line\"><span>resolve</span></span>\n<span class=\"line\"><span>data:  true</span></span></code></pre>\n<p>很明顯可以看到 <code>finally</code> block 的 promise 執行完之後，才執行 <code>return “true”</code></p>\n<h2 id=\"可以用什麼替代原文作者的寫法\">可以用什麼替代原文作者的寫法？</h2>\n<h3 id=\"只在-finally-block-寫-control-flow-statementnot-perfect\">只在 <code>finally</code> block 寫 control-flow statement（not perfect）</h3>\n<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>\n<span class=\"line\"><span>  try {</span></span>\n<span class=\"line\"><span>    console.log(\"try\");</span></span>\n<span class=\"line\"><span>  } finally {</span></span>\n<span class=\"line\"><span>    cleanup();</span></span>\n<span class=\"line\"><span>    return \"true\"</span></span>\n<span class=\"line\"><span>  }</span></span>\n<span class=\"line\"><span>};</span></span></code></pre>\n<p>有網友提供這樣的寫法，可以在 <code>cleanup</code> 後接著 return value，一石二鳥。不過如果今天 <code>try</code> block 裡面需要 await data 或做其它事，必須還得在外面 assign 一個變數，才能讓 <code>finally</code> block return data 出去，像這樣：</p>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">  let</span><span style=\"color:#E1E4E8\"> data;</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">  try</span><span style=\"color:#E1E4E8\"> {</span></span>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  } </span><span style=\"color:#F97583\">finally</span><span style=\"color:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">    cleanup</span><span style=\"color:#E1E4E8\">();</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">    return</span><span style=\"color:#E1E4E8\"> data;</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">};</span></span></code></pre>\n<p>另外就是，假如希望 <code>catch</code> block 能 throw error 或 return error 到外面去，讓外部知道有 error，這種寫法可能就不適合了。</p>\n<h3 id=\"老老實實地在-trycatch-執行完的下一行做-cleanup\">老老實實地在 <code>try…catch</code> 執行完的下一行做 cleanup</h3>\n<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>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#B392F0\">    resolve</span><span style=\"color:#E1E4E8\">();</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  });</span></span>\n<span class=\"line\"></span>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">  try</span><span style=\"color:#E1E4E8\"> {</span></span>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">    return</span><span style=\"color:#9ECBFF\"> \"true\"</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  } </span><span style=\"color:#F97583\">catch</span><span style=\"color:#E1E4E8\"> (error) {</span></span>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">};</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#B392F0\">fn</span><span style=\"color:#E1E4E8\">();</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">cleaup</span><span style=\"color:#E1E4E8\">();</span></span></code></pre>\n<p>夠粗暴，且簡單與直覺。</p>\n<h3 id=\"用-finally\">用 <code>.finally()</code></h3>\n<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>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#B392F0\">    resolve</span><span style=\"color:#E1E4E8\">();</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  });</span></span>\n<span class=\"line\"></span>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">  try</span><span style=\"color:#E1E4E8\"> {</span></span>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">    return</span><span style=\"color:#9ECBFF\"> \"true\"</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  } </span><span style=\"color:#F97583\">catch</span><span style=\"color:#E1E4E8\"> (error) {</span></span>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">};</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#B392F0\">fn</span><span style=\"color:#E1E4E8\">()</span></span>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  })</span></span>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#B392F0\">    cleanup</span><span style=\"color:#E1E4E8\">();</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  });</span></span></code></pre>\n<p>可以用 <code>.finally()</code> 的方式來做取代，這種方式基本上可以確保 return 值之後，才會進到 <code>.finally()</code>，缺點就是寫起來會變得又臭又長?</p>\n<p>要寫得比較完整的話，可以再加上 <code>.catch()</code></p>\n<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>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#B392F0\">    resolve</span><span style=\"color:#E1E4E8\">();</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  });</span></span>\n<span class=\"line\"></span>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">  try</span><span style=\"color:#E1E4E8\"> {</span></span>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">    return</span><span style=\"color:#9ECBFF\"> \"true\"</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  } </span><span style=\"color:#F97583\">catch</span><span style=\"color:#E1E4E8\"> (error) {</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">    throw</span><span style=\"color:#E1E4E8\"> error;</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">};</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#B392F0\">fn</span><span style=\"color:#E1E4E8\">()</span></span>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  })</span></span>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  })</span></span>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#B392F0\">    cleanup</span><span style=\"color:#E1E4E8\">();</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  });</span></span></code></pre>\n<h3 id=\"另一個比較常見的寫法用-promise-包著\">另一個比較常見的寫法：用 <code>Promise</code> 包著</h3>\n<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>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#B392F0\">    resolve</span><span style=\"color:#E1E4E8\">();</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  });</span></span>\n<span class=\"line\"></span>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">    try</span><span style=\"color:#E1E4E8\"> {</span></span>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    } </span><span style=\"color:#F97583\">catch</span><span style=\"color:#E1E4E8\"> (error) {</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">      reject</span><span style=\"color:#E1E4E8\">(error);</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  });</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">};</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#B392F0\">fn</span><span style=\"color:#E1E4E8\">()</span></span>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  })</span></span>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  })</span></span>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#B392F0\">    cleanup</span><span style=\"color:#E1E4E8\">();</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  });</span></span></code></pre>\n<h2 id=\"千萬別這麼做\">千萬別這麼做</h2>\n<p>看到原文串有人舉一個例子表示千萬別這麼做，否則會討厭你自己</p>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">  try</span><span style=\"color:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">    return</span><span style=\"color:#9ECBFF\"> \"2. return from try\"</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  } </span><span style=\"color:#F97583\">catch</span><span style=\"color:#E1E4E8\"> (error) {</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">    return</span><span style=\"color:#9ECBFF\"> \"3. return from catch\"</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  } </span><span style=\"color:#F97583\">finally</span><span style=\"color:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">    return</span><span style=\"color:#9ECBFF\"> \"4. return from finally\"</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}</span></span>\n<span class=\"line\"></span>\n<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>\n<p>log 的順序將會是：</p>\n<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>\n<span class=\"line\"><span>2. return from finally</span></span></code></pre>\n<p>沒錯，直接略過 <code>try</code> 跟 <code>catch</code> block</p>\n<p>即使你今天在 <code>try</code> block 丟出一個錯誤，也不會 return <code>catch</code> block 的字串</p>\n<h2 id=\"總結\">總結</h2>\n<p><code>finally</code> block 目前看起來存在著些違反直覺的機制，可能會在無意中寫出令你驚喜的情況，看起來能不用就不用，似乎也沒有非得使用的必要。若仍要使用，請絕對要小心服用，並有意識地在知道 <code>finally</code> block 的機制下去做使用。</p>\n<h3 id=\"網友分享另一個變形題\">網友分享另一個變形題</h3>\n<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>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">    return</span><span style=\"color:#9ECBFF\"> \"fourth\"</span><span style=\"color:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  };</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#F97583\">  try</span><span style=\"color:#E1E4E8\"> {</span></span>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#F97583\">    return</span><span style=\"color:#B392F0\"> zit</span><span style=\"color:#E1E4E8\">();</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  } </span><span style=\"color:#F97583\">finally</span><span style=\"color:#E1E4E8\"> {</span></span>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">};</span></span>\n<span class=\"line\"></span>\n<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>\n<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>\n<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>\n<span class=\"line\"><span style=\"color:#E1E4E8\">})();</span></span></code></pre>\n<p>猜猜答案會是什麼？</p>\n<details>\n  <summary>Answer</summary>\n<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>\n<span class=\"line\"><span>second</span></span>\n<span class=\"line\"><span>third</span></span>\n<span class=\"line\"><span>data:  fourth</span></span></code></pre>\n<p>(<a href=\"https://x.com/berliangor/status/1898252789639520282\">ref</a>)</p>\n</details>",
            "url": "https://boundarylesstacks.com/post/2025-the-finally-behavior-in-try-catch-of-javascript/",
            "title": "The `finally` behavior in `try…catch` of JavaScript",
            "summary": "finally behavior in JavaScript",
            "date_modified": "2025-04-19T00:00:00.000Z",
            "date_published": "2025-04-19T00:00:00.000Z",
            "author": {
                "name": "RZ Huang",
                "url": "https://boundarylesstacks.com/about/"
            }
        },
        {
            "id": "https://boundarylesstacks.com/post/2025-test-first-post/",
            "content_html": "<p>Hello everyone, this is the first post of the blog</p>",
            "url": "https://boundarylesstacks.com/post/2025-test-first-post/",
            "title": "First post",
            "summary": "Test",
            "date_modified": "2025-01-01T00:00:00.000Z",
            "date_published": "2025-01-01T00:00:00.000Z",
            "author": {
                "name": "RZ Huang",
                "url": "https://boundarylesstacks.com/about/"
            }
        }
    ]
}