我们在开发过程中大多会用到promise,想必大家对promise的使用都很熟练了,今天我们就来实现一个简单的promise,实现的效果如有出入还往指正。
Promise/A+规范:
首先重新阅读了下A+的规范:
promise代表了一个异步操作的最终结果,主要是通过then方法来注册成功以及失败的情况,
Promise/A+历史上说是实现了Promise/A的行为并且考虑了一些不足之处,他并不关心如何创建,完成,拒绝Promise,只考虑提供一个可协作的then方法。
术语:
promise是一个拥有符合上面的特征的then方法的对象或者方法。
thenable是定义了then方法的对象或者方法
value是任何合法的js的值(包括undefined,thenable或者promise)
exception是一个被throw申明抛出的值
reason是一个指明了为什么promise被拒绝
整体结构
我们先来梳理一下整体的结果,以便后续好操作
class MyPromise { constructor(fn){ } resolve(){ } then(){ } reject(){ } catch(){ } }
Promise理论知识
摘抄至 #docs/promise#Promise-all
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
resolve
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;当前的值为接收的值
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 } reject(reason){ if(this.state !== 'pending') return; this.state = 'rejected'; this.value = reason } }
当reject执行,接收到一个值之后;状态就由 pending -> rejected;当前的值为接收的值
then
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) } } }) } }