一、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/zh-hant/n/190597.html