摘要:本文博客原文地址我們在開發過程中大多會用到,想必大家對的使用都很熟練了,今天我們就來實現一個簡單的,實現的效果如有出入還往指正。對象的狀態不受外界影響。對象代表一個異步操作,有三種狀態進行中已成功和已失敗。
本文博客原文地址
我們在開發過程中大多會用到promise,想必大家對promise的使用都很熟練了,今天我們就來實現一個簡單的promise,實現的效果如有出入還往指正。
整體結構我們先來梳理一下整體的結果,以便后續好操作
class MyPromise { constructor(fn){ } resolve(){ } then(){ } reject(){ } catch(){ } }Promise理論知識
摘抄至 http://es6.ruanyifeng.com/#do...
Promise對象有以下兩個特點。
(1)對象的狀態不受外界影響。Promise對象代表一個異步操作,有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗)。只有異步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。這也是Promise這個名字的由來,它的英語意思就是“承諾”,表示其他手段無法改變。
(2)一旦狀態改變,就不會再變,任何時候都可以得到這個結果。Promise對象的狀態改變,只有兩種可能:從pending變為fulfilled和從pending變為rejected。只要這兩種情況發生,狀態就凝固了,不會再變了,會一直保持這個結果,這時就稱為 resolved(已定型)。如果改變已經發生了,你再對Promise對象添加回調函數,也會立即得到這個結果。這與事件(Event)完全不同,事件的特點是,如果你錯過了它,再去監聽,是得不到結果的。
總結一下就是promise有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗),還有就是狀態的改變只能是pending -> fulfilled 或者 pending -> rejected,這些很重要
實現構造函數現在我們開始實現構造函數
class MyPromise { constructor(fn){ if(typeof fn !== "function") { throw new TypeError(`MyPromise fn ${fn} is not a function`) } this.state = "pending"; this.value = void 0; fn(this.resolve.bind(this),this.reject.bind(this)) } ... }
構造函數接收一個參數fn,且這個參數必須是一個函數,因為我們一般這樣使用new Promise((resolve,reject)=>{});
然后初始化一下promise的狀態,默認開始為pending,初始化value的值。
fn接收兩個參數,resolve、reject
class MyPromise { constructor(fn){ if(typeof fn !== "function") { throw new TypeError(`MyPromise fn ${fn} is not a function`) } this.state = "pending"; this.value = void 0; fn(this.resolve.bind(this),this.reject.bind(this)) } resolve(value){ if(this.state !== "pending") return; this.state = "fulfilled"; this.value = value } ... }
當resolve執行,接收到一個值之后;狀態就由 pending -> fulfilled;當前的值為接收的值
rejectclass MyPromise { constructor(fn){ if(typeof fn !== "function") { throw new TypeError(`MyPromise fn ${fn} is not a function`) } this.state = "pending"; this.value = void 0; fn(this.resolve.bind(this),this.reject.bind(this)) } resolve(value){ if(this.state !== "pending") return; this.state = "fulfilled"; this.value = value } reject(reason){ if(this.state !== "pending") return; this.state = "rejected"; this.value = reason } }
當reject執行,接收到一個值之后;狀態就由 pending -> rejected;當前的值為接收的值
thenclass MyPromise { constructor(fn){ if(typeof fn !== "function") { throw new TypeError(`MyPromise fn ${fn} is not a function`) } this.state = "pending"; this.value = void 0; fn(this.resolve.bind(this),this.reject.bind(this)) } resolve(value){ if(this.state !== "pending") return; this.state = "fulfilled"; this.value = value } reject(reason){ if(this.state !== "pending") return; this.state = "rejected"; this.value = reason } then(fulfilled,rejected){ if (typeof fulfilled !== "function" && typeof rejected !== "function" ) { return this; } if (typeof fulfilled !== "function" && this.state === "fulfilled" || typeof rejected !== "function" && this.state === "rejected") { return this; } return new MyPromise((resolve,reject)=>{ if(fulfilled && typeof fulfilled === "function" && this.state === "fulfilled"){ let result = fulfilled(this.value); if(result && typeof result.then === "function"){ return result.then(resolve,reject) }else{ resolve(result) } } if(rejected && typeof rejected === "function" && this.state === "rejected"){ let result = rejected(this.value); if(result && typeof result.then === "function"){ return result.then(resolve,reject) }else{ resolve(result) } } }) } }
then的實現比較關鍵,首先有兩個判斷,第一個判斷傳的兩個參數是否都是函數,如果部不是return this執行下一步操作。
第二個判斷的作用是,比如,現在狀態從pending -> rejected;但是中間代碼中有許多個.then的操作,我們需要跳過這些操作執行.catch的代碼。如下面的代碼,執行結果只會打印1
new Promise((resolve,reject)=>{ reject(1) }).then(()=>{ console.log(2) }).then(()=>{ console.log(3) }).catch((e)=>{ console.log(e) })
我們繼續,接下來看到的是返回了一個新的promise,真正then的實現的確都是返回一個promise實例。這里不多說
下面有兩個判斷,作用是判斷是rejected還是fulfilled,首先看fulfilled,如果是fulfilled的話,首先執行fulfilled函數,并把當前的value值傳過去,也就是下面這步操作,res就是傳過去的value值,并執行了(res)=>{console.log(res)}這段代碼;執行完成之后我們得到了result;也就是2這個結果,下面就是判斷當前結果是否是一個promise實例了,也就是下面注釋了的情況,現在我們直接執行resolve(result);
new Promise((resolve,reject)=>{ resolve(1) }).then((res)=>{ console.log(res) return 2 //return new Promise(resolve=>{}) })
剩下的就不多說了,可以debugger看看執行結果
catchclass MyPromise { ... catch(rejected){ return this.then(null,rejected) } }完整代碼
class MyPromise { constructor(fn){ if(typeof fn !== "function") { throw new TypeError(`MyPromise fn ${fn} is not a function`) } this.state = "pending"; this.value = void 0; fn(this.resolve.bind(this),this.reject.bind(this)) } resolve(value){ if(this.state !== "pending") return; this.state = "fulfilled"; this.value = value } reject(reason){ if(this.state !== "pending") return; this.state = "rejected"; this.value = reason } then(fulfilled,rejected){ if (typeof fulfilled !== "function" && typeof rejected !== "function" ) { return this; } if (typeof fulfilled !== "function" && this.state === "fulfilled" || typeof rejected !== "function" && this.state === "rejected") { return this; } return new MyPromise((resolve,reject)=>{ if(fulfilled && typeof fulfilled === "function" && this.state === "fulfilled"){ let result = fulfilled(this.value); if(result && typeof result.then === "function"){ return result.then(resolve,reject) }else{ resolve(result) } } if(rejected && typeof rejected === "function" && this.state === "rejected"){ let result = rejected(this.value); if(result && typeof result.then === "function"){ return result.then(resolve,reject) }else{ resolve(result) } } }) } catch(rejected){ return this.then(null,rejected) } }測試
new MyPromise((resolve,reject)=>{ console.log(1); //reject(2) resolve(2) console.log(3) setTimeout(()=>{console.log(4)},0) }).then(res=>{ console.log(res) return new MyPromise((resolve,reject)=>{ resolve(5) }).then(res=>{ return res }) }).then(res=>{ console.log(res) }).catch(e=>{ console.log("e",e) }) 執行結果: > 1 > 3 > 2 > 5 > 4
原生promise
new Promise((resolve,reject)=>{ console.log(1); //reject(2) resolve(2) console.log(3) setTimeout(()=>{console.log(4)},0) }).then(res=>{ console.log(res) return new Promise((resolve,reject)=>{ resolve(5) }).then(res=>{ return res }) }).then(res=>{ console.log(res) }).catch(e=>{ console.log("e",e) }) 執行結果: > 1 > 3 > 2 > 5 > 4GitHub
wclimb
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97698.html
摘要:如果狀態是等待態的話,就往回調函數中函數,比如如下代碼就會進入等待態的邏輯以上就是簡單版實現實現一個符合規范的接下來大部分代碼都是根據規范去實現的。 為更好的理解, 推薦閱讀Promise/A+ 規范 實現一個簡易版 Promise 在完成符合 Promise/A+ 規范的代碼之前,我們可以先來實現一個簡易版 Promise,因為在面試中,如果你能實現出一個簡易版的 Promise ...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。異步編程入門的全稱是前端經典面試題從輸入到頁面加載發生了什么這是一篇開發的科普類文章,涉及到優化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結思考,循序漸進的理解 TypeScript。 網絡基礎知識之 HTTP 協議 詳細介紹 HTT...
摘要:的執行與狀態無關當得到狀態不論成功或失敗后就會執行,原文鏈接參考鏈接對象 同期異步系列文章推薦談一談javascript異步javascript異步中的回調javascript異步與promisejavascript異步之Promise.resolve()、Promise.reject()javascript異步之Promise then和catchjavascript異步之async...
摘要:所以增加了異步函數,提高了代碼可讀性,對不太熟悉的人而言,幫助就更大了。因為異步函數去掉了所有回調。這就是此代碼有效的原因它和以下一樣代碼更易讀正如上面示例所見,與回調和代碼相比,異步函數代碼看起來非常簡單。 這篇文章詳細講解了JavaScript中的異步函數。 JavaScript中的異步代碼在很短的時間內從回調發展為Promise,再到ES2017的異步函數,現在我們可以像編寫同步...
摘要:轉載自是什么呢根據的定義是一個被用于延時計算的最終結果的占位符這個怎么理解呢比如說,我要去麥當勞買點吃的,下單以后人家會先給你一個訂單號,等人家外賣做好了,會提示你,并用那個訂單小票來換取你真正的食物,在這時候,那個訂單小票就是你這頓飯的 轉載自: http://www.lht.ren/article/3/ Promise是什么呢?根據ecma-262的定義: Promise是一個被用...
閱讀 2260·2023-04-25 14:50
閱讀 1234·2021-10-13 09:50
閱讀 1866·2019-08-30 15:56
閱讀 1840·2019-08-29 15:29
閱讀 2887·2019-08-29 15:27
閱讀 3548·2019-08-29 15:14
閱讀 1192·2019-08-29 13:01
閱讀 3299·2019-08-26 14:06