You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请教:JavaScript Promise中`<..>.get().then().then().catch().finally()`与`<...>.get().then().catch().then().finally()`的执行差异

Key Differences Between These Two Promise Chain Structures

Great question—this gets to the heart of how Promise error handling and chaining works, and the two structures behave very differently when errors are involved. Let’s break them down step by step.

1. <..>.get().then().then().catch().finally()

This structure uses a single catch as a global safety net for all operations that come before it in the chain. Here’s what happens:

  • The catch will catch any errors (or rejected Promises) from the initial get() call, the first then() handler, or the second then() handler.
  • If an error occurs in any of those three steps, the chain will skip all remaining then() handlers before the catch and jump straight to error handling.
  • Once the catch finishes executing (assuming it doesn’t throw a new error), the finally() will run as expected (it always runs, regardless of success or failure).

Example Code

fetch('/api/data')
  .then(res => {
    if (!res.ok) throw new Error('Invalid response');
    return res.json();
  })
  .then(data => {
    if (!data.length) throw new Error('Empty data set');
    return processRawData(data);
  })
  .catch(err => {
    console.error('Something went wrong in fetch or processing:', err);
    return defaultData;
  })
  .finally(() => {
    console.log('Request chain finished—cleaning up');
  });

In this case:

  • If fetch fails, or the first then throws, or the second then throws, we hit the catch immediately, skipping any unexecuted thens.

2. <...>.get().then().catch().then().finally()

Here, the catch only covers errors from the get() call and the first then() handler. The key difference is what happens after the catch:

  • If an error occurs in get() or the first then(), we enter the catch. Once the catch handles the error (and returns a resolved Promise, which it does by default unless you throw), the next then() will execute regardless of the earlier error.
  • If get() and the first then() succeed, the chain skips the catch and moves straight to the next then().
  • Important: Any errors thrown in the second then() won’t be caught by this catch—you’d need an additional catch at the end to handle those.

Example Code

fetch('/api/data')
  .then(res => {
    if (!res.ok) throw new Error('Invalid response');
    return res.json();
  })
  .catch(err => {
    console.error('Fetch or first parse failed:', err);
    return fallbackData; // Return a default to keep the chain going
  })
  .then(data => {
    // This runs whether the first part succeeded or failed!
    console.log('Displaying data:', data);
    return renderData(data);
  })
  .finally(() => {
    console.log('Request chain finished—cleaning up');
  });

In this case:

  • If fetch fails, we use the catch to return fallback data, then the next then() renders that fallback.
  • If the first then succeeds, we skip the catch and render the real data.
  • If renderData throws an error, there’s no catch to handle it (unless we add one after this then).

Core Takeaways

AspectFirst Structure (then().then().catch())Second Structure (then().catch().then())
Error CoverageCatches errors from get(), then1, then2Catches errors only from get() and then1
Execution After ErrorSkips remaining thens before catchRuns the next then() after catch handles the error
Use CaseGeneral error handling for the entire chain before the catchRecovering from early errors to continue the chain

内容的提问来源于stack exchange,提问作者user13041346

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 14:22:42