一、Promise.finally()定义及用途
Promise.finally()是ES2018新增的一个方法,可以被用于Promise链中任何位置,不管Promise实例最终的状态如何,都会执行finally中的内容。
finally()处理完毕不会改变Promise的状态,仍然返回和原来Promise状态一样的对象,常用于处理资源清理、取消网络请求时的任务取消等。
二、Promise.finally()的语法和返回
promiseInstance.finally(() => { //...执行的代码 });
对于链式的Promise,Promise.finally()返回的Promise还是按照上一个状态来处理。如果中途抛出异常,会影响到后面的执行。但是,finally()不会改变Promise原有状态。
三、Promise.finally()的用法介绍
1. Promise链式调用中的finally()
const promise = new Promise((resolve, reject) => { setTimeout(() => { resolve('成功') }, 1000) }) promise.then(res => { console.log(res + '后执行') return res }).finally(() => { console.log('先执行finally()') })
上述代码中,setTimeout设定1秒后resolve一个成功结果。在then后面链接了finally,在控制台中输出顺序如下:
- 任务一:成功后执行
- 任务二:先执行finally()
2. 处理ajax请求的finally()
axios.get('/user/12345') .then(function(res) { console.log(res.data); }) .catch(function(error) { console.log(error); }) .finally(function() { console.log('不管请求成功或失败,我都会被执行'); });
上述代码中,异步的ajax调用,不管是成功还是失败,finally承担着资源释放和清理的作用。
4. Promise.all()使用finally()
Promise.all()会在所有异步操作都执行完成后才会被解析,这时就需要利用finally()的特性来处理。
const p1 = Promise.resolve(1); const p2 = Promise.resolve(2); const p3 = new Promise((resolve) => setTimeout(resolve, 1000, 3)) Promise.all([p1, p2, p3]).then(result => console.log(result)).finally(() => { console.log('我最后被执行了') })
上述代码中,Promise.all()等待异步的操作执行完毕,Promise.all()的then()会接收一个数组,包含了全部异步完成后的结果。属性结果之后,finally()被执行,表示所有异步任务都已经完成了。
5. tslib库实现Promise.finally()
npm install tslib
导入tslib库中的polyfill使得我们可以在任何情况下使用Promise.finall()方法。如果浏览器自带的Promise没有实现finally()方法,就会导入tslib中的polyfill。
import 'tslib' Promise.resolve(1).finally(() => { console.log('使用了tslib库的finally()') })
四、Promise.finally()的局限性
Promise.finaly()目前也存在着一定的局限性,在箭头函数中无法使用break、continue等语句,因为和直接用代码块的finally不同,箭头函数里的组合语句不可被终止。
五、结论
Promise.finally()是一个十分实用的方法,舒展了Promise链式调用的各个阶段,可以为清理资源、取消操作、错误处理等行为提供很好的支持。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/190597.html