您好,登錄后才能下訂單哦!
這篇文章主要介紹了JS中Promise的使用及封裝方法是什么的相關(guān)知識,內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇JS中Promise的使用及封裝方法是什么文章都會有所收獲,下面我們一起來看看吧。
Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。
簡單說就是一個(gè)容器,里面保存著某個(gè)未來才會結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果。
從語法上說,Promise 是一個(gè)對象,從它可以獲取異步操作的消息。Promise 提供統(tǒng)一的 API,各種異步操作都可以用同樣的方法進(jìn)行處理。
1. 對象的狀態(tài)不受外界影響。Promise 對象代表一個(gè)異步操作,有三種狀態(tài):pending(進(jìn)行中)、fulfilled(已成功)和 rejected(已失?。V挥挟惒讲僮鞯慕Y(jié)果,可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無法改變這個(gè)狀態(tài)。這也是 Promise 這個(gè)名字的由來,它的英語意思就是“承諾”,表示其他手段無法改變
2. 一旦狀態(tài)改變,就不會再變,任何時(shí)候都可以得到這個(gè)結(jié)果。Promise 對象的狀態(tài)改變,只有兩種可能:從 pending 變?yōu)?fulfilled 和從 pending 變?yōu)?rejected。只要這兩種情況發(fā)生,狀態(tài)就凝固了,不會再變了,會一直保持這個(gè)結(jié)果,這時(shí)就稱為 resolved(已定型)。如果改變已經(jīng)發(fā)生了,你再對 Promise 對象添加回調(diào)函數(shù),也會立即得到這個(gè)結(jié)果。這與事件(Event)完全不同,事件的特點(diǎn)是,如果你錯(cuò)過了它,再去監(jiān)聽,是得不到結(jié)果的。
3. 將異步操作以同步操作的流程表達(dá)出來,避免了層層嵌套的回調(diào)函數(shù)(回調(diào)地獄)
1. 無法取消 Promise,一旦新建它就會立即執(zhí)行,無法中途取消
2. 如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯(cuò)誤,不會反應(yīng)到外部
3. 當(dāng)處于pending狀態(tài)時(shí),無法得知目前進(jìn)展到哪一個(gè)階段(剛剛開始還是即將完成)
ES6 規(guī)定,Promise 對象是一個(gè)構(gòu)造函數(shù),用來生成 Promise 實(shí)例。通過在函數(shù)內(nèi)部 return 一個(gè) Promise 對象的實(shí)例,這樣就可以使用 Promise 的屬性和方法進(jìn)行下一步操作了。    
Promise 構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù),該函數(shù)的兩個(gè)參數(shù)分別是 resolve 和 reject。它們是兩個(gè)函數(shù),由 JavaScript 引擎提供,不用自己部署
const promise = new Promise(function(resolve, reject) { if (/* 異步操作成功 */){ resolve(value) } else { reject(error) } })
then()方法就是把原來的回調(diào)寫法分離出來,在異步操作執(zhí)行完后,用鏈?zhǔn)秸{(diào)用的方式執(zhí)行回調(diào)函數(shù)。
而 Promise的優(yōu)勢就在于這個(gè)鏈?zhǔn)秸{(diào)用。
我們可以在 then 方法中繼續(xù)寫 Promise 對象并返回,然后繼續(xù)調(diào)用 then 來進(jìn)行回調(diào)操作。
resolve 的用法
let promise = new Promise(function(resolve, reject) { console.log('Promise') resolve('已完成') }); promise.then(function(data) { console.log('resolved.',data) }) console.log('Hi!') // Promise // Hi! // resolved. 123
reject 的用法
reject 方法就是把 Promise 的狀態(tài)置為已失?。≧ejected),這時(shí) then 方法執(zhí)行“失敗”情況的回調(diào)(then 方法的第二參數(shù))
let promise = new Promise(function(resolve, reject) { reject('NO') }); promise.then(function(data) { console.log('resolved.',data) },function(data){ console.log('rejected.',data) }) // rejected. NO
如果異步操作拋出錯(cuò)誤,當(dāng)前 Promise 對象狀態(tài)就會變?yōu)?rejected,就會調(diào)用 catch 方法指定的回調(diào)函數(shù),處理這個(gè)錯(cuò)誤。
另外,then 方法指定的回調(diào)函數(shù),如果運(yùn)行中拋出錯(cuò)誤,也會被 catch 方法捕獲。
catch 方法返回的也是一個(gè) Promise 對象,因此后面還可以接著調(diào)用then方法。
const promise = new Promise(function(resolve, reject) { resolve('OK') }) promise.then(function(data) { console.log(data) console.log(num) }).catch(function(err) { console.log(err) }) // OK // ReferenceError: num is not defined
finally 方法用于指定不管 Promise 對象最后狀態(tài)如何,在執(zhí)行完 then 或 catch 指定的回調(diào)函數(shù)以后,都會執(zhí)行 finally 方法指定的回調(diào)函數(shù)。
finally 方法的回調(diào)函數(shù)不接受任何參數(shù),在 finally 方法里面的操作,與狀態(tài)無關(guān),不依賴于 Promise 的執(zhí)行結(jié)果。
// 服務(wù)器使用 Promise 處理請求,然后使用 finally 方法關(guān)掉服務(wù)器 server.listen(port) .then(function () { // ... }) .finally(server.stop)
Promise 的 all 方法(傳入一個(gè)數(shù)組,每一項(xiàng)分別是一個(gè) Promise 實(shí)例)提供了并行執(zhí)行異步操作的能力,并且在所有異步操作執(zhí)行完(所有實(shí)例的狀態(tài)都變成 fulfilled)或者 只要有一個(gè) Promise 實(shí)例的狀態(tài)變?yōu)?reject,Promise.all 的狀態(tài)就會變?yōu)?reject,然后執(zhí)行回調(diào)??梢詫?shù)組里的 Promise 看成是 “與” 關(guān)系。
應(yīng)用場景:打開網(wǎng)頁時(shí),預(yù)先加載需要用到的各種資源如圖片、flash 以及各種靜態(tài)文件。所有的都加載完后,我們再進(jìn)行頁面的初始化
//買作業(yè)本 function cutUp() { console.log('挑作業(yè)本') var p = new Promise(function(resolve, reject) { //做一些異步操作 console.log('挑好購買作業(yè)本') resolve('新的作業(yè)本') }) return p } //買筆 function boil() { console.log('挑筆芯') var p = new Promise(function(resolve, reject) { //做一些異步操作 console.log('挑好購買筆芯') resolve('新的筆芯') }); return p } Promise.all([cutUp(),boil()]).then(function(res) { console.log("寫作業(yè)的工具都買好了") console.log(res) }) // 挑作業(yè)本 // 挑好購買作業(yè)本 // 挑筆芯 // 挑好購買筆芯 // 寫作業(yè)的工具都買好了 // ["新的作業(yè)本", "新的筆芯"]
Promise.race 方法( 傳入一個(gè)數(shù)組,每一項(xiàng)分別是 Promise 實(shí)例 )的用法與 all 一樣,異步操作同樣是并行執(zhí)行的。只不過 all 是等所有異步操作都執(zhí)行完畢后才執(zhí)行 then 回調(diào)。race 可以看到 是 “或” 關(guān)系,只要有一個(gè)異步操作執(zhí)行完畢,就會立刻執(zhí)行 then 回調(diào)。
應(yīng)用場景:用 race 給某個(gè)異步請求設(shè)置超時(shí)時(shí)間,并且在超時(shí)后執(zhí)行相應(yīng)的操作
//買作業(yè)本 function cutUp() { console.log('挑作業(yè)本') var p = new Promise(function(resolve, reject) { //做一些異步操作 console.log('挑好購買作業(yè)本') resolve('新的作業(yè)本') }) return p } //買筆 function boil() { console.log('挑筆芯') var p = new Promise(function(resolve, reject){ //做一些異步操作 console.log('挑好購買筆芯') resolve('新的筆芯') }) return p } Promise.race([cutUp(),boil()]).then(function(res){ console.log("寫作業(yè)的工具都買好了") console.log(res) }) // 挑作業(yè)本 // 挑好購買作業(yè)本 // 挑筆芯 // 挑好購買筆芯 // 寫作業(yè)的工具都買好了 // 新的作業(yè)本
Promise.allSettled() 方法接受一組 Promise 實(shí)例作為參數(shù),包裝成一個(gè)新的 Promise 實(shí)例 。
只有等到所有這些參數(shù)實(shí)例都返回結(jié)果,不管是 fulfilled 還是 rejected,包裝實(shí)例才會結(jié)束。
Promise.allSettled()的返回值該是一個(gè)數(shù)組,數(shù)組里每個(gè)對象都有 status 屬性,該屬性的值只可能是字符串 fulfilled 或字符串rejected。
fulfilled 時(shí),對象有 value 屬性,rejected 時(shí)有 reason 屬性,對應(yīng)兩種狀態(tài)的返回值。
應(yīng)用場景:不關(guān)心異步操作的結(jié)果,只確保所有異步操作都結(jié)束
//買作業(yè)本 function cutUp() { console.log('挑作業(yè)本') var p = new Promise(function(resolve, reject) { //做一些異步操作 console.log('挑好購買作業(yè)本') resolve('新的作業(yè)本') }) return p } //買筆 function boil() { console.log('挑筆芯') var p = new Promise(function(resolve, reject){ //做一些異步操作 console.log('挑好購買筆芯') reject('購買不了,沒錢了') }) return p } Promise.allSettled([cutUp(),boil()]).then(function(res){ console.log("寫作業(yè)的工具沒有買齊") console.log(res) }) // 挑作業(yè)本 // 挑好購買作業(yè)本 // 挑筆芯 // 挑好購買筆芯 // 寫作業(yè)的工具沒有買齊 // [ // {status: "fulfilled", value: "新的作業(yè)本"} // {status: "rejected", reason: "購買不了,沒錢了"} // ]
function promiseM(callback) { this.status = 'pendding' this.msg = '' callback((data) => { this.status = 'resolve' this.msg = data },(err) => { if (this.status === 'resolve') return this.status = 'reject' this.msg = err }) } promiseM.prototype.then = function () { let cb = arguments let that = this let timer = setInterval(function () { if(that.status == 'resolve') { cb[0](that.msg) clearInterval(timer) } else if(that.status == 'reject') { if(!cb[1]) { clearInterval(timer) throw that.msg + ' No Exit' } else { cb[1](that.msg) clearInterval(timer) } } }, 500) } function fn() { return new promiseM(function (resolve, reject) { resolve('success') }) } fn().then(function (res) { console.log(res) }) // success
關(guān)于“JS中Promise的使用及封裝方法是什么”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“JS中Promise的使用及封裝方法是什么”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。