在Node.js中,使用Promise.prototype.finally

点击左上方关注 “ 新钛云服 ”

最近Promise.prototype.finally() 达到了TC39提案流程的第4阶段,这意味着其建议已被接受,并现已成为ECMAScript规范最新草案的一部分。由此看来,将其放入Node.js仅是时间问题。

本文将向您展示:

如何使用Promise.prototype.finally()以及如何编写自己的简化polyfill

一、什么是Promise.prototype.finally()

假设您创建了一个新的promise:

您可以使用.then()函数将诺言链接在一起。

请注意,它.then()带有两个功能参数。第一个是onFulfilled(),如果兑现了promise,就会调用。第二个是onRejected(),如果拒绝了promise,则调用。

promise是可以处于以下三种状态之一的状态机

1.待定:基本操作正在进行中,但promise尚未实现或被拒绝

2.已完成:基础操作已成功完成,并且promise现在具有关联的价值

3.拒绝:基础操作由于某种原因而失败,并且promise现在具有关联的错误

此外,已兑现或已兑现的promise被称为“已结算”。

虽然.then()是承诺链的核心机制,但它并不是唯一的机制。promise也有一个.catch()功能是方便的错误处理。

该.catch()函数只是.then()使用onRejected处理程序而不使用onFulfilled处理程序的便捷速记:

就像.catch(),该.finally()功能是的便捷快捷方式.then()。区别在于,在兑现promise时即履行或拒绝promise时,.finally()执行功能onFinally。

.finally()在撰写本文时,该功能尚未包含在任何Node.js版本中,但promise.prototype.finally在npm上的模块具有polyfill。

上面的脚本将同时打印“已完成”和“已拒绝”,这是因为onFinally在实现promise时将调用处理程序,而不管promise是实现还是拒绝。然而,onFinally处理程序没有收到任何参数,所以你不能告诉的promise是否已兑现或拒绝。

该finally()函数返回一个承诺,让你可以更链.then(),.catch()和.finally()调用到返回值。finally()回报的promise将兑现与之挂钩的promise。例如,即使onFinally处理程序返回“ bar” ,下面的脚本仍将打印“ foo ”。

同样,即使该onFinally函数未触发任何错误,下面的脚本仍将打印“ foo” 。

上述脚本演示与工作的一个重要的细节finally():finally()不会为您处理promise rejections。finally()如何处理promise rejections值得更仔细的研究。

二、错误处理

该finally()功能并不意味着处理promise rejections。事实上,它会在函数执行后明确地抛出错误onFinally()。以下脚本将打印未处理的promise rejections警告。

像一样try/catch/finally,你通常想.finally()在一个链之后链接.catch()。

但是,该finally()函数返回一个Promise,因此没有什么可以阻止您在.catch()after之后链接.finally()。特别是,如果您的onFinally处理程序可能出错,例如,如果发出HTTP请求,则应.catch()在末尾添加a以处理可能发生的任何错误。

三、简化的Polyfill

我认为最简单的方法是编写自己的实现。该.finally()函数是一个不错的选择,因为官方的polyfill只有45行,并且大多数对于简单的概念证明不是必需的。

这是此简单的finally()polyfill可以解决的测试案例。下面的脚本应打印'foo'5次。

以下是简化的polyfill。

此实现背后的关键思想是onFinally处理程序可以返回promise。如果确实如此,则您需要.then()兑现该promise,并解决或拒绝最初的promise达成的目标。

您可以显式检查onFinally处理程序的返回值是否为Promise。但此时Promise.resolve()已经为您完成了此操作,并为您节省了几条if语句。

所以你只需确保跟踪初始promise所确定的值或错误,并确保返回的promise从finally()实现到初始已解决的值res,或重新抛出初始被拒绝的错误err。

四、继续

该Promise.prototype.finally()功能是撰写本文时8个第4阶段TC39提案之一,这意味着finally()Node.js还有7个其他新的核心语言功能。

该finally()功能是8个新功能中最令人兴奋的功能之一,因为它有望使异步操作后的清理工作更加整洁。例如,下面是我现在正在生产中运行的代码,在finally()函数执行完后,迫切需要释放锁。

对promise链感到困惑吗?异步/等待是在Node.js中撰写承诺的最佳方法。Await为您处理promise rejections,因此未处理的promise rejections就消失了。

我的新电子书Mastering Async / Await旨在使您对异步/等待的基础知识以及异步/等待如何在几小时内适应JavaScript生态系统有一个全面的了解。

*本文译自http://thecodebarbarian.com/using-promise-finally-in-node-js.html,版权归原作者所有

了解新钛云服

当IPFS遇见云服务|新钛云服与冰河分布式实验室达成战略协议

新钛云服正式获批工信部ISP/IDC(含互联网资源协作)牌照

深耕专业,矗立鳌头,新钛云服获千万Pre-A轮融资

新钛云服,打造最专业的Cloud MSP+,做企业业务和云之间的桥梁

新钛云服一周年,完成两轮融资,服务五十多家客户

上海某仓储物流电子商务公司混合云解决方案

新钛云服出品的部分精品技术干货

低代码开发,全民开发,淘汰职业程序员!

国内主流公有云VPC使用对比及总结

万字长文:云架构设计原则|附PDF下载

刚刚,OpenStack 第 19 个版本来了,附28项特性详细解读!

Ceph OSD故障排除|万字经验总结

七个用于Docker和Kubernetes防护的安全工具

运维人的终身成长,从清单管理开始|万字长文!

OpenStack与ZStack深度对比:架构、部署、计算存储与网络、运维监控等

什么是云原生?

IT混合云战略:是什么、为什么,如何构建?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值