ECMAScript 2018 引入了 Promise.prototype.finally() 方法,这个方法可以在 Promise 执行结束后,无论是 resolve 还是 reject,都会执行一段代码。这个方法非常有用,但是在一些老版本的浏览器中可能不被支持,这时候我们需要一些解决办法。
Promise.prototype.finally() 的用法
Promise.prototype.finally() 方法接受一个函数作为参数,这个函数会在 Promise 执行结束后被调用,无论是 resolve 还是 reject。这个方法不会改变 Promise 的状态,并且会返回一个新的 Promise 对象,这个对象的状态和原来的 Promise 对象一样,但是它的值是 finally() 方法返回的值。
下面是一个使用 finally() 方法的示例代码:
-- -------------------- ---- ------- -------- --------------- - ------ --- ----------------- ------- -- - ------------- -- - -------------- -------- ----------- -- ------ --- - --------------- ------------ -- - -------------------- -- ------------ -- - --------------------- -- ----------- -- - ------------------ -------- ----------- ---
在这个示例中,我们定义了一个异步函数 asyncFunction(),它返回一个 Promise 对象。我们使用 then() 方法来处理异步函数的 resolve 和 catch() 方法来处理 reject。最后,我们使用 finally() 方法来执行一段无论如何都会被执行的代码。
解决办法
如果你的浏览器不支持 Promise.prototype.finally() 方法,不要担心,我们可以使用一些解决办法来解决这个问题。
1. 使用 polyfill
Polyfill 是一段 JavaScript 代码,它可以在不支持某个新特性的浏览器中模拟这个特性。我们可以使用一个 polyfill 来模拟 Promise.prototype.finally() 方法。
下面是一个 polyfill 的示例代码:
-- -------------------- ---- ------- -- ---------------------------- - ------------------------- - ------------------ - ----- - - ----------------- ------ ---------- ----- -- ----------------------------- -- ------- ------ -- ----------------------------- -- - ----- ------- -- -- -- -
这个 polyfill 模拟了 Promise.prototype.finally() 方法,如果浏览器不支持 finally() 方法,它就会在 Promise.prototype 上添加这个方法。
2. 手动实现 Promise.prototype.finally() 方法
如果你不想使用 polyfill,你也可以手动实现 Promise.prototype.finally() 方法。
下面是一个手动实现的示例代码:
Promise.prototype.finally = function(callback) { return this.then( result => Promise.resolve(callback()).then(() => result), error => Promise.resolve(callback()).then(() => { throw error; }) ); };
这个手动实现的方法和 polyfill 的方法很相似,它也是在 Promise.prototype 上添加了 finally() 方法。
结论
Promise.prototype.finally() 方法是一个非常有用的方法,它可以在 Promise 执行结束后无论是 resolve 还是 reject 都会被执行。但是在一些老版本的浏览器中可能不被支持,我们可以使用 polyfill 或者手动实现的方法来解决这个问题。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6758062ceadad513cd4128a1