es6 Promise.done(),Promise.finally()
promise對象的finally函數(shù)為什么要這樣寫
ES6的 Promise API提供的方法不是很多,有些有用的方法可以自己部署。下面介紹如何部署兩個(gè)不在ES6之中、但很有用的方法。
done()
Promise 對象的回調(diào)鏈,不管以then方法或catch方法結(jié)尾,要是最后一個(gè)方法拋出錯(cuò)誤,都有可能無法捕捉到(因?yàn)?Promise內(nèi)部的錯(cuò)誤不會冒泡到全局)。因此,我們可以提供一個(gè)done方法,總是處于回調(diào)鏈的尾端,保證拋出任何可能出現(xiàn)的錯(cuò)誤。
Promise.prototype.done = function (onFulfilled, onRejected) {
this
.then(onFulfilled, onRejected)
.catch(function (reason) {
// 拋出一個(gè)全局錯(cuò)誤
setTimeout(() => {
throw reason
}, 0)
})
}
從上面代碼可見,done方法的使用,可以像then方法那樣用,提供fulfilled和rejected狀態(tài)的回調(diào)函數(shù),也可以不提供任何參數(shù)。但不管怎樣,done都會捕捉到任何可能出現(xiàn)的錯(cuò)誤,并向全局拋出。
finally()
finally方法用于指定不管Promise對象最后狀態(tài)如何,都會執(zhí)行的操作。它與done方法的最大區(qū)別,它接受一個(gè)普通的回調(diào)函數(shù)作為參數(shù),該函數(shù)不管怎樣都必須執(zhí)行。
下面是一個(gè)例子,服務(wù)器使用Promise處理請求,然后使用finally方法關(guān)掉服務(wù)器。
Promise.prototype.finally = function (callback) {
let P = this.constructor
return this.then(
value => P.resolve(callback()).then(() => value),
reason => P.resolve(callback()).then(() => {
throw reason
})
)
}
上面代碼中,不管前面的 Promise是fulfilled還是rejected,都會執(zhí)行回調(diào)函數(shù)callback。
這個(gè)是轉(zhuǎn)換為ES5之后的。
Promise.prototype.finally = function (callback) {
var P = this.constructor
return this.then(function (value) {
return P.resolve(callback()).then(function () {
return value
})
}, function (reason) {
return P.resolve(callback()).then(function () {
throw reason
})
})
}
要這么寫的原因是在于,finally其實(shí)并不一定是這個(gè)promise鏈的最后一環(huán),相對而言,其實(shí)done才是。
因?yàn)?code>finally可能之后還有then和catch等等,所以其必須要返回一個(gè)promise對象。