JavaScript模擬實(shí)現(xiàn)Promise功能的示例代碼
模擬Promise的功能, 按照下面的步驟,一步一步
1. 新建是個(gè)構(gòu)造函數(shù)
2. 傳入一個(gè)可執(zhí)行函數(shù) 函數(shù)的入?yún)⒌谝粋€(gè)為 fullFill函數(shù) 第二個(gè)為 reject函數(shù); 函數(shù)立即執(zhí)行, 參數(shù)函數(shù)異步執(zhí)行
3. 狀態(tài)一旦更改就不可以變更 只能 pending => fulfilled 或者 pending => rejected
4. then 的時(shí)候要處理入?yún)⒌那闆r successCallback 和failCallback 均可能為非函數(shù)
默認(rèn)的 failCallback 一定要將異常拋出, 這樣下一個(gè)promise便可將其捕獲 異常冒泡的目的
5. then 中執(zhí)行回調(diào)的時(shí)候要捕獲異常 將其傳給下一個(gè)promise
- 如果promise狀態(tài)未變更 則將回調(diào)方法添加到對應(yīng)隊(duì)列中
- 如果promise狀態(tài)已經(jīng)變更 需要異步處理成功或者失敗回調(diào)
- 因?yàn)榭赡艹霈F(xiàn) 回調(diào)結(jié)果和當(dāng)前then返回的Promise一致 從而導(dǎo)致死循環(huán)問題
6. catch只是then的一種特殊的寫法 方便理解和使用
7. finally 特點(diǎn)
- 不過resolve或者reject都會(huì)執(zhí)行
- 回調(diào)沒有參數(shù)
- 返回一個(gè)Promise 且值可以穿透到下一個(gè)then或者catch
8. Promise.resolve, Promise.reject 根據(jù)其參數(shù)返回對應(yīng)的值 或者狀態(tài)的Promise即可
9. Proise.all 特點(diǎn)
- 返回一個(gè)Promise
- 入?yún)⑹菙?shù)組 resolve的情況下出參也是數(shù)組 且結(jié)果順序和調(diào)用順序一致
- 所有的值或者promise都完成才能resolve 所有要計(jì)數(shù)
- 只要有一個(gè)為reject 返回的Promise便reject
10. Proise.race 特點(diǎn)
- 返回一個(gè)Promise
- 入?yún)⑹菙?shù)組 那么出參根據(jù)第一個(gè)成功或者失敗的參數(shù)來確定
- 只要有一個(gè)resolve 或者reject 便更改返回Promise的狀態(tài)
const PENDING = 'pending' //等待 const FULFILLED = 'fulfilled' //成功 const REJECTED = 'rejected' //失敗 const fulfilledCallback = [] //成功回調(diào)函數(shù) const rejectedCallback = [] //失敗回調(diào)函數(shù) class MyPromise { constructor (executor) { try{ executor(this.resolve, this.reject) } catch (e){ this.reject(e) } } status = PENDING//promise的狀態(tài) value = undefined//成功之后的值 reason = undefined//失敗之后的值 fulfilledCallback = [] //成功回調(diào)函數(shù) rejectedCallback = [] //失敗回調(diào)函數(shù) resolve = value => { //如果狀態(tài)不是等待, 阻止程序繼續(xù)往下執(zhí)行 if(this.status !== PENDING){ return } this.status = FULFILLED this.value = value //判斷成功回調(diào)是否存在,如果存在, 調(diào)用 // this.fulfilledCallback && this.fulfilledCallback(this.value) while(this.fulfilledCallback.length) this.fulfilledCallback.shift()() } reject = reason => { //如果狀態(tài)不是等待, 阻止程序繼續(xù)往下執(zhí)行 if(this.status !== PENDING){ return } this.status = REJECTED this.reason = reason //判斷失敗回調(diào)是否存在,如果存在, 調(diào)用 // this.rejectedCallback && this.rejectedCallback(this.reason) while(this.rejectedCallback.length) this.rejectedCallback.shift()() } then = (fulfilledCallback, rejectedCallback) => { fulfilledCallback = fulfilledCallback ? fulfilledCallback : value => value rejectedCallback = rejectedCallback ? rejectedCallback : reason => {throw reason} let promise2 = new MyPromise((resolve, reject) => { //判斷狀態(tài) if(this.status === FULFILLED){ setTimeout(() => { try { //判斷x 傳過來的可能是promise,先查看promise返回的結(jié)果,在決定是用resolve還是reject, //如果是普通值,直接調(diào)用resolve let x = fulfilledCallback(this.value) //外面加載完,才能獲取到promise2,用異步解決 resolvePromise(promise2,x,resolve, reject) } catch (error) { reject(error) } },0) }else if(this.status === REJECTED){ setTimeout(() => { try { //判斷x 傳過來的可能是promise,先查看promise返回的結(jié)果,在決定是用resolve還是reject, //如果是普通值,直接調(diào)用resolve let x = rejectedCallback(this.reason) //外面加載完,才能獲取到promise2,用異步解決 resolvePromise(promise2,x,resolve, reject) } catch (error) { reject(error) } },0) }else{ //等待狀態(tài) this.fulfilledCallback.push(() => { setTimeout(() => { try { //判斷x 傳過來的可能是promise,先查看promise返回的結(jié)果,在決定是用resolve還是reject, //如果是普通值,直接調(diào)用resolve let x = fulfilledCallback(this.value) //外面加載完,才能獲取到promise2,用異步解決 resolvePromise(promise2,x,resolve, reject) } catch (error) { reject(error) } },0) }); this.rejectedCallback.push(() => { setTimeout(() => { try { //判斷x 傳過來的可能是promise,先查看promise返回的結(jié)果,在決定是用resolve還是reject, //如果是普通值,直接調(diào)用resolve let x = rejectedCallback(this.reason) //外面加載完,才能獲取到promise2,用異步解決 resolvePromise(promise2,x,resolve, reject) } catch (error) { reject(error) } },0) }); } }) return promise2 } static all (array) { let result= [] let index = 0; return new MyPromise((resolve, reject) => { function addData (key, value) { result[key] = value index++ if (index === array.length) { resolve(result) } } for (let i = 0; i < array.length; i++) { if (array[i] instanceof MyPromise) { //promise對象 array[i].then(value => addData(i, value), reason => reject(reason)) } else { //普通值, 放到數(shù)組里 addData(i, array[i]) } } }) } static resolve (value) { if(value instanceof MyPromise) return value return new MyPromise(resolve => resolve(value)) } finally (callback) { return this.then(value => { return MyPromise.resolve(callback()).then(() => value) }, reason => { return MyPromise.resolve(callback()).then(() => {throw reason}) }) } catch (rejectedCallback) { return this.then(undefined, rejectedCallback) } } function resolvePromise(promise2,x,resolve, reject){ if(x === promise2){ return reject(new TypeError('啦啦啦啦')) } if(x instanceof MyPromise){ //是promise //往下直接傳 x.then(resolve,reject) }else{ //普通值 resolve(x) } } module.exports = MyPromise;
到此這篇關(guān)于JavaScript模擬實(shí)現(xiàn)Promise功能的示例代碼的文章就介紹到這了,更多相關(guān)JavaScript實(shí)現(xiàn)Promise功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實(shí)現(xiàn)文字跟隨鼠標(biāo)特效
這篇文章主要介紹了JavaScript如何實(shí)現(xiàn)文字跟隨鼠標(biāo)特效,d代碼簡單易操作,感興趣的朋友可以參考下2015-08-08詳解使用Nuxt.js快速搭建服務(wù)端渲染(SSR)應(yīng)用
這篇文章主要介紹了詳解使用Nuxt.js快速搭建服務(wù)端渲染(SSR)應(yīng)用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-03-03layui關(guān)閉層級、簡單監(jiān)聽的實(shí)例
今天小編就為大家分享一篇layui關(guān)閉層級、簡單監(jiān)聽的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09ElementPlus?Tag標(biāo)簽用法小結(jié)
這篇文章主要介紹了ElementPlus?Tag標(biāo)簽用法,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09JS基于onclick事件實(shí)現(xiàn)單個(gè)按鈕的編輯與保存功能示例
這篇文章主要介紹了JS基于onclick事件實(shí)現(xiàn)單個(gè)按鈕的編輯與保存功能,結(jié)合實(shí)例形式分析了JS實(shí)現(xiàn)onclick響應(yīng)事件的轉(zhuǎn)換相關(guān)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02用javascrpt將指定網(wǎng)頁保存為Excel的代碼
這段代碼在服務(wù)器中沒有權(quán)限,可以保存在本地,存為htm文件,運(yùn)行即可,就可以把文本內(nèi)容存為excel文件了2008-01-01