JavaScript面試必考之實(shí)現(xiàn)手寫Promise
Promise手寫
Promise作為面試必考題,Promise的手寫也是面試官必問的問題,所以對(duì)于Promise我們一定要了解透徹
框架
(function(window) { MyPromise.prototype.then = function (onResolved, onRejected) {} MyPromise.prototype.catch = function (onRejected) {} function MyPromise(executor){ function resolve(value){} function reject(error){} try{ executor(resolve, reject) }catch(error){ reject(error) } } window.MyPromise = MyPromise }(window))
完整代碼
(function (window) { //將.then,.catch方法掛載在MyPromise原型上 MyPromise.prototype.then = function (onResolved, onRejected) {//.then接受兩個(gè)回調(diào)函數(shù),resolved狀態(tài)和rejeced狀態(tài) // .then返回一個(gè)promise對(duì)象 return new MyPromise((resolve, reject) => { let self = this; if (self.status === 'pending') {//如果MyPromise狀態(tài)為pending,將兩個(gè)回調(diào)函數(shù)push進(jìn)回調(diào)數(shù)組中等待 this.callbacks.push({ onResolved, onRejected }) } else if (self.status === 'resolved') { //如果MyPromise狀態(tài)為resolved,將onResolved直接調(diào)用 setTimeout(() => { //檢查.then中的回調(diào)有沒有return返回值 const result = onResolved(self.data) //如果沒有return返回值,默認(rèn)返回promise對(duì)象 if (result instanceof MyPromise) { result.then((res => resolve(res), err => reject(err))) return result } else { resolve(result) } }) } else { setTimeout(() => { onResolved(self.data) }) } }) } MyPromise.prototype.catch = function (onRejected) { //.catch接受一個(gè)回調(diào)函數(shù) if (this.status === 'pending') { // 將回調(diào)函數(shù)放入callbacks數(shù)組中 this.callbacks.push({ onRejected }) } else if (this.status === 'rejected') { setTimeout(() => { onRejected(this.data) }) } } // MyPromise構(gòu)造函數(shù)接受一個(gè)執(zhí)行函數(shù) function MyPromise(executor) { const self = this; self.data = undefined; self.callbacks = [] //設(shè)置promise對(duì)象初始狀態(tài)為pending self.status = 'pending' //執(zhí)行函數(shù)第一個(gè)參數(shù)為resolve回調(diào) function resolve(value) { //如果狀態(tài)不是pending,則直接返回 if (self.status !== 'pending') { return } // 執(zhí)行resolve,promise對(duì)象狀態(tài)變更 self.status = 'resolved'; // 拿到resolve中的值 self.data = value; // 調(diào)用callbacks中的回調(diào)函數(shù) if (self.callbacks.length > 0) { setTimeout(() => { self.callbacks.forEach(callbacksObj => { callbacksObj.onResolved(value) }); }) } } // 執(zhí)行函數(shù)第二個(gè)參數(shù)為rejecr回調(diào) function reject(error) { //如果狀態(tài)不是pending,則直接返回 if (self.status !== 'pending') { return } // 執(zhí)行resolve,promise對(duì)象狀態(tài)變更 self.status = 'rejected'; // 拿到resolve中的值 self.data = error; // 調(diào)用callbacks中的回調(diào)函數(shù) if (self.callbacks.length > 0) { setTimeout(() => { self.callbacks.forEach(callbacksObj => { callbacksObj.onRejected(value) }); }) } } //使用try catch捕獲錯(cuò)誤 try { // 在try內(nèi)執(zhí)行執(zhí)行函數(shù) executor(resolve, reject) } catch (error) { // 如果出錯(cuò),默認(rèn)執(zhí)行reject reject(error); } } window.MyPromise = MyPromise }(window))
測(cè)試
resolve
let MyPromiseTest = new MyPromise((resolve, reject) => { resolve('resolve') }) MyPromiseTest.then(res => { console.log(res); }) // resolve
let MyPromiseTest = new MyPromise((resolve, reject) => { resolve('resolve'); }) MyPromiseTest.then(res => { console.log(res); }) .then(res => { console.log('我是.then()后面的.then()'); }) // resolve // 我是.then()后面的.then()
reject
let MyPromiseTest = new MyPromise((resolve, reject) => { reject('reject') }) MyPromiseTest.catch(err => { console.log(err); }) // reject
let MyPromiseTest = new MyPromise((resolve, reject) => { console.log(a); }) MyPromiseTest.catch(err => { console.log('捕獲錯(cuò)誤' + ':' + err); }) // 捕獲錯(cuò)誤:ReferenceError: a is not defined
到此這篇關(guān)于JavaScript面試必考之實(shí)現(xiàn)手寫Promise的文章就介紹到這了,更多相關(guān)JavaScript手寫Promise內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS實(shí)現(xiàn)單張或多張圖片持續(xù)無縫滾動(dòng)的示例代碼
這篇文章主要介紹了JS實(shí)現(xiàn)單張或多張圖片持續(xù)無縫滾動(dòng)效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05input鏈接頁面、打開新網(wǎng)頁等等的具體實(shí)現(xiàn)
input可以鏈接到某頁、返回、打開新網(wǎng)頁、打開無邊框的新窗口等等,本文整理了一些,感興趣的朋友可以參考下2013-12-12淺談JavaScript構(gòu)造樹形結(jié)構(gòu)的一種高效算法
這篇文章主要介紹了JavaScript構(gòu)造樹形結(jié)構(gòu)的一種高效算法,對(duì)算法感興趣的同學(xué),可以參考下2021-05-05javascript實(shí)現(xiàn)時(shí)間格式輸出FormatDate函數(shù)
這篇文章主要介紹了javascript實(shí)現(xiàn)時(shí)間格式輸出FormatDate函數(shù),可實(shí)現(xiàn)fmt標(biāo)簽一樣對(duì)日期時(shí)間型內(nèi)容格式輸入的功能,是非常實(shí)用的技巧,需要的朋友可以參考下2015-01-01javascript實(shí)現(xiàn)的登陸遮罩效果匯總
小編給大家推薦幾款使用Javascript實(shí)現(xiàn)的遮罩效果登陸框,其實(shí)這種效果是很常見的,在許多互動(dòng)的社區(qū)及其它的一些地方,彈出框應(yīng)用想當(dāng)流行,在不妨礙網(wǎng)頁運(yùn)行的情況下,用戶可以輸入登錄信息,實(shí)現(xiàn)完美登錄。2015-11-11JavaScript自動(dòng)設(shè)置IFrame高度的小例子
JavaScript自動(dòng)設(shè)置IFrame高度的小例子,需要的朋友可以參考一下2013-06-06