Open ForeveHG opened 5 years ago
finally方法返回一个Promise,在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数,上一个最直接的版本:
Promise.prototype.myFinally = function (callback) { return this.then(callback,callback) }
这种写法callback将接收到前一步promise返回的值,那么finally返回的promise中的value就是callback这个函数的返回值,但ES6的Promise.finally不是这样的,看下面的例子
// Promise {<resolved>: 2} new Promise(resolve => { resolve(1) }).myFinally(res => { return 2 }) // 但ES6的finally返回的却是Promise {<resolved>: 1} new Promise(resolve => { resolve(1) }).finally(res => { return 2 })
也就是说finally返回的promise的value应该是前一个promise的返回值,callback这个函数本身得返回值不作为finally返回的promise的value,callback只是无论成功失败都要执行的一个函数而已,所以修改一下代码
Promise.prototype.myFinally = function (callback) { return this.then(value => { callback(); return value; },reason => { callback(); throw reason; }) }
测试一下
//自己定义的finally: Promise {<resolved>: 1} new Promise(resolve => { resolve(1) }).myFinally(res => { return 2 }) // ES6的finally: Promise {<resolved>: 1} new Promise(resolve => { resolve(1) }).finally(res => { return 2 })
但当callback是一个异步操作,并返回一个promise对象时,这种写法并不会等待这个异步操作执行结束后再进行下一步,但ES6中promise的finally是会等待callback返回的promise对象resolve后再进行下一步的,所以需要把代码更改为
Promise.prototype.myFinally = function (callback) { return this.then( value => Promise.resolve(callback()).then(() => value), reason => Promise.resolve(callback()).then(() => Promise.reject(reason)) ) }
可以查看这个polyfill,
/** * @this {Promise} */ function finallyConstructor(callback) { var constructor = this.constructor; return this.then( function(value) { // @ts-ignore return constructor.resolve(callback()).then(function() { return value; }); }, function(reason) { // @ts-ignore return constructor.resolve(callback()).then(function() { // @ts-ignore return constructor.reject(reason); }); } ); }
其中用到了constructor,我感觉主要是为了兼容性,毕竟也有很多自己实现的Promise库
谢谢,网上找了好多相关资料,都是不清不楚的,终于在你这看明白了。关注你啦哈哈哈
finally方法返回一个Promise,在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数,上一个最直接的版本:
这种写法callback将接收到前一步promise返回的值,那么finally返回的promise中的value就是callback这个函数的返回值,但ES6的Promise.finally不是这样的,看下面的例子
也就是说finally返回的promise的value应该是前一个promise的返回值,callback这个函数本身得返回值不作为finally返回的promise的value,callback只是无论成功失败都要执行的一个函数而已,所以修改一下代码
测试一下
但当callback是一个异步操作,并返回一个promise对象时,这种写法并不会等待这个异步操作执行结束后再进行下一步,但ES6中promise的finally是会等待callback返回的promise对象resolve后再进行下一步的,所以需要把代码更改为
可以查看这个polyfill,
其中用到了constructor,我感觉主要是为了兼容性,毕竟也有很多自己实现的Promise库