本文博客原文地址git
咱们在开发过程当中大多会用到promise
,想必你们对promise
的使用都很熟练了,今天咱们就来实现一个简单的promise
,实现的效果若有出入还往指正。es6
咱们先来梳理一下总体的结果,以便后续好操做github
class MyPromise { constructor(fn){ } resolve(){ } then(){ } reject(){ } catch(){ } }
摘抄至 http://es6.ruanyifeng.com/#do...
Promise
对象有如下两个特色。promise
(1)对象的状态不受外界影响。Promise对象表明一个异步操做,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操做的结果,能够决定当前是哪种状态,任何其余操做都没法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其余手段没法改变。异步
(2)一旦状态改变,就不会再变,任什么时候候均可以获得这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种状况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。若是改变已经发生了,你再对Promise对象添加回调函数,也会当即获得这个结果。这与事件(Event)彻底不一样,事件的特色是,若是你错过了它,再去监听,是得不到结果的。函数
总结一下就是promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),还有就是状态的改变只能是pending -> fulfilled 或者 pending -> rejected,这些很重要测试
如今咱们开始实现构造函数this
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
debug
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
;当前的值为接收的值code
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 } }
当reject
执行,接收到一个值以后;状态就由 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)) } 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
看看执行结果
class 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 > 4