ES9中新增了Promise.prototype.finally(),我们来学习下
在之前的学习中,我们知道了then方法和catch方法,现在我们可以想象在一个完整的外卖订餐流程中
then()→ 外卖送到后开吃(成功)catch()→ 送餐出错处理(失败)finally()→ 无论成败都要被告知(必执行)
            
            
              js
              
              
            
          
          // 订餐流程
orderFood()
  .then(food => console.log(` 享用${food}`))     // 成功吃上 
  .catch(err => console.log(" 投诉:", err))       // 失败处理
  .finally(() => console.log(" 收拾碗筷"));       // 必执行 
        特性描述
- 无视成败:无论Promise成功/失败都执行
 - 无参数:不接收任何结果值
 - 链式传递:返回原Promise结果(不改变结果)
 
一些常见的使用场景
关闭加载动画
            
            
              js
              
              
            
          
          let isLoading = true;
 
fetchData()
  .then(data => render(data))
  .catch(err => showError(err))
  .finally(() => {
    isLoading = false; // 必关闭加载状态
    spinner.hide(); 
  });
        记录操作结束
            
            
              js
              
              
            
          
          trackUserAction()
  .finally(() => {
    console.log(`[${new  Date()}] 用户操作完成`);
    // 无论成功失败都记录
  });
        替代重复代码(避免then/catch双写)
            
            
              js
              
              
            
          
          // 旧写法(ES6)
fetchData()
  .then(data => {
    process(data);
    cleanup(); // 成功时需要清理
  })
  .catch(err => {
    handleError(err);
    cleanup(); // 失败时也要清理 → 重复!
  });
 
// 新写法(ES9)
fetchData()
  .then(process)
  .catch(handleError)
  .finally(cleanup); // 只需写一次 
        finally中的异步操作
            
            
              js
              
              
            
          
          deleteFile()
  .finally(() => {
    return backupLog(); // 返回新Promise
  })
  .then(() => console.log(" 备份完成"))
  .catch(err => console.log(" 备份失败", err));
        finally抛出错误
            
            
              js
              
              
            
          
          saveData()
  .finally(() => {
    throw new Error("清理异常"); // 会覆盖原结果
  })
  .catch(err => console.log(err));  // 捕获清理错误
        与async/await结合
            
            
              js
              
              
            
          
          async function fetchWithCleanup() {
  try {
    const data = await fetchAPI();
  } catch (err) {
    handleError(err);
  } finally { // 等效语法 
    releaseResources();
  }
}
        与传统方案相比
| 场景 | ES6方案 | ES9 finally方案 | 
优势 | 
|---|---|---|---|
| 关闭数据库连接 | then/catch中重复调用db.close() | 
.finally(db.close) | 
避免代码重复 | 
| 隐藏加载动画 | 每个分支写spinner.hide() | 
集中写在finally | 减少50%代码量 | 
| 释放文件句柄 | 可能遗漏错误分支 | 确保100%执行 | 防止资源泄漏 | 
牢记
finally作为Promise的兜底保障,必执行 (无视成功失败),资源管理 (防止内存泄漏), 代码精简(消除重复逻辑)