一起手写吧!Promise!
1、Promise 的声明
首先呢,promise肯定是一个类,我们就用class来声明。
- 由于
new Promise((resolve, reject)=>{})
,所以传入一个参数(函数),秘籍里叫他executor,传入就执行。 - executor里面有两个参数,一个叫resolve(成功),一个叫reject(失败)。
- 由于resolve和reject可执行,所以都是函数,我们用let声明。
class Promise{ // 构造器 constructor(executor){ // 成功 let resolve = () => { }; // 失败 let reject = () => { }; // 立即执行 executor(resolve, reject); } }
解决基本状态
秘籍对Promise有规定:
-
Promise存在三个状态(state)pending、fulfilled、rejected
-
pending(等待态)为初始态,并可以转化为fulfilled(成功态)和rejected(失败态)
-
成功时,不可转为其他状态,且必须有一个不可改变的值(value)
-
失败时,不可转为其他状态,且必须有一个不可改变的原因(reason)
-
new Promise((resolve, reject)=>{resolve(value)})
resolve为成功,接收参数value,状态改变为fulfilled,不可再次改变。 -
new Promise((resolve, reject)=>{reject(reason)})
reject为失败,接收参数reason,状态改变为rejected,不可再次改变。 -
若是executor函数报错 直接执行reject();
于是乎,我们获得以下代码
class Promise{ constructor(executor){ // 初始化state为等待态 this.state = 'pending'; // 成功的值 this.value = undefined; // 失败的原因 this.reason = undefined; let resolve = value => { // state改变,resolve调用就会失败 if (this.state === 'pending') { // resolve调用后,state转化为成功态 this.state = 'fulfilled'; // 储存成功的值 this.value = value; } }; let reject = reason => { // state改变,reject调用就会失败 if (this.state === 'pending') { // reject调用后,state转化为失败态 this.state = 'rejected'; // 储存失败的原因 this.reason = reason; } }; // 如果executor执行报错,直接执行reject try{ executor(resolve, reject); } catch (err) { reject(err); } } }
then方法
秘籍规定:Promise有一个叫做then的方法,里面有两个参数:onFulfilled,onRejected,成功有成功的值,失败有失败的原因
- 当状态state为fulfilled,则执行onFulfilled,传入this.value。当状态state为rejected,则执行onRejected,传入this.reason
- onFulfilled,onRejected如果他们是函数,则必须分别在fulfilled,rejected后被调用,value或reason依次作为他们的第一个参数
class Promise{ constructor(executor){...} // then 方法 有两个参数onFulfilled onRejected then(onFulfilled,onRejected) { // 状态为fulfilled,执行onFulfilled,传入成功的值 if (this.state === 'fulfilled') { onFulfilled(this.value); }; // 状态为rejected,执行onRejected,传入失败的原因 if (this.state === 'rejected') { onRejected(this.reason); }; } }
这下武学初成,可以对付对付江湖小杂毛了,但是对于带setTimeout的江洋大盗还是没辙。