Promise.prototype.finally的作用是什么

发布时间:2021-10-12 11:52:57 作者:iii
来源:亿速云 阅读:136
# Promise.prototype.finally的作用是什么

## 引言

在现代JavaScript异步编程中,Promise已成为处理异步操作的核心工具。ES2018引入的`Promise.prototype.finally`方法为Promise链式调用提供了重要的补充。本文将深入探讨`finally`方法的作用、使用场景、实现原理以及注意事项。

## 一、基本概念

### 1. Promise回顾
Promise对象表示异步操作的最终完成(或失败)及其结果值,有三种状态:
- pending(进行中)
- fulfilled(已成功)
- rejected(已失败)

### 2. finally方法定义
`finally()`方法返回一个Promise,无论原始Promise是fulfilled还是rejected,都会执行指定的回调函数。

```javascript
promise
  .then(result => { ... })
  .catch(error => { ... })
  .finally(() => { 
    // 无论成功失败都会执行
  });

二、核心作用

1. 执行清理逻辑

无论Promise成功与否都需要执行的代码:

let loading = true;

fetch('/data')
  .finally(() => {
    loading = false; // 无论请求成功失败都要关闭加载状态
  });

2. 替代重复代码

避免在then/catch中重复相同逻辑:

// 没有finally的写法
promise
  .then(result => {
    doCleanup();
    return result;
  })
  .catch(error => {
    doCleanup();
    throw error;
  });

// 使用finally优化
promise
  .finally(doCleanup);

3. 保持Promise链完整

finally会传递原始Promise的结果:

Promise.resolve(2)
  .finally(() => {})
  .then(v => console.log(v)); // 仍输出2

三、技术特性

1. 返回值处理

Promise.resolve('hello')
  .finally(() => 'ignored')
  .then(v => console.log(v)); // 仍输出'hello'

2. 与then/catch的区别

方法 接收参数 影响结果 执行条件
then 仅fulfilled时
catch 仅rejected时
finally 所有情况都会执行

3. 执行顺序示例

Promise.resolve()
  .then(() => console.log('then1'))
  .finally(() => console.log('finally'))
  .then(() => console.log('then2'));

// 输出顺序:
// then1 → finally → then2

四、实际应用场景

1. 资源释放

let connection;
db.connect()
  .then(conn => {
    connection = conn;
    return conn.query();
  })
  .finally(() => {
    if(connection) connection.close();
  });

2. UI状态管理

function fetchData() {
  setLoading(true);
  
  return api.getData()
    .finally(() => {
      setLoading(false);
    });
}

3. 日志记录

trackEvent('API_CALL_START');

apiCall()
  .finally(() => {
    trackEvent('API_CALL_END');
  });

五、实现原理

1. Polyfill实现

Promise.prototype.finally = function(callback) {
  return this.then(
    value => Promise.resolve(callback()).then(() => value),
    reason => Promise.resolve(callback()).then(() => { throw reason })
  );
};

2. 关键点解析

  1. 通过then方法确保回调执行
  2. Promise.resolve处理callback可能返回的thenable
  3. 保持原始Promise的值或原因

六、注意事项

1. 错误处理

如果finally回调抛出错误,会覆盖原始结果:

Promise.resolve('ok')
  .finally(() => {
    throw new Error('error in finally');
  })
  .catch(e => console.log(e)); // 捕获的是finally中的错误

2. 异步回调

finally中的异步操作不会阻塞链式调用:

Promise.resolve()
  .finally(async () => {
    await delay(1000); // 不会等待
  })
  .then(() => console.log('立即执行'));

3. 浏览器兼容性

需要关注ES2018+的支持情况,必要时使用polyfill。

七、总结

Promise.prototype.finally为Promise链式调用提供了以下核心价值: 1. 代码简洁:消除then/catch中的重复逻辑 2. 逻辑清晰:明确分离业务逻辑和清理代码 3. 可靠性增强:确保关键清理逻辑必定执行

作为Promise API的重要补充,finally方法使异步代码的组织更加优雅和健壮,是现代JavaScript开发中不可或缺的工具。

扩展阅读

”`

推荐阅读:
  1. ManualResetEvent的作用是什么
  2. .htaccess的作用是什么

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

上一篇:Gridview有什么用

下一篇:在K8S大规模场景下Service性能该如何优化

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》