看过不少种 promise 的实现,一直想本身写一个,吭哧了好久,终于写出来了(先不写 all 等方法和 reject 方法,后期在 issues 中补充),就拿它做为第一篇博客吧promise
代码浏览器
let proB = new PromiseB((resolve) => { console.log('promiseB: resolve'); resolve('then1') })
proB.then(value => {
console.log('then1', value)
return 'then2'
}).then(//建立pro3
data => {
return new PromiseB((resolve) => {//是pro4
setTimeout(() => {
console.log('非正常then2:', data)
resolve('then3')
}, 1000)
})
}).then(value => {
console.log('数据then3', value)
return 'then4'
}).then(value => {
console.log('数据then4', value)
return 'then5'
}).then().then(
value => { console.log('then5:', value) }
)
复制代码
本身实现执行结果: 异步
promise 执行的结果: async
先看一下使用中须要注意的方面函数
具体实现思路ui
class PromiseB{
constructor(excutor){
this.state='pending'// 'pending'|'fulfilled'|'redected'
excutor(this.resolve)
}
then=(onFunfilled,onRejected)=>{//class properties语法,目前谷歌浏览器已经支持了
return new PromiseB(/*这里应该有一个函数参数*/)
}
}
复制代码
class PromiseB{
constructor(excutor) {
this.state='pending'// 'pending'|'fulfilled'|'redected'
this.value = null
this.asyncObj = {}
excutor(this.resolve)
}
then=(onFunfilled,onRejected)=>{//class properties语法,目前谷歌浏览器已经支持了
return new PromiseB(/*这里应该有一个函数参数*/)
}
resolve = (newValue) => {}
}
复制代码
then = (onFUlfilled) => {
return new PromiseB(resolve => {
if (this.state === "pending") {
this.asyncObj={ onFUlfilled, resolve };
} else {
if(!onFUlfilled)return resolve(this.value)
resolve(onFUlfilled(this.value));
}
});
};
复制代码
resolve = newValue => {
this.state = "fulfilled";
this.value = newValue;
};
复制代码
resolve = newValue => {
if (newValue && newValue.then) {
newValue.then(this.resolve);
} else {
this.state = "fulfilled";
this.value = newValue;
if(!asyncObj.onFUlfilled && asyncObj.resolve)return asyncObj.resolve(this.value)
asyncObj.resolve(asyncObj.onFUlfilled(this.value))
}
};
复制代码
所有代码实现:this
class PromiseB {
constructor(excutor) {
this.state = "pending";
this.value = null;
this.asyncObj = {};
excutor(this.resolve);
}
then = onFulfilled =>
new PromiseB(resolve => {
if (this.state === "pending")
return (this.asyncObj = { onFulfilled, resolve });
if (!onFulfilled) return resolve(this.value);
resolve(onFulfilled(this.value));
});
resolve=value=>{
if(value&&value.then){
value.then(this.resolve)
}else{
this.state='fulfilled'
this.value=value
setTimeout(() => {
const {onFulfilled,resolve} = this.asyncObj
if(onFulfilled&&resolve)resolve(onFulfilled(this.value))
if(!onFulfilled&&resolve)resolve(this.value)
},
0);
}
}
}
复制代码
由于在参数不为 promise 而且 asyncObj 有值的状况下,看第 23 行代码,这里实际上是一个递归,onFulfiled 其实就是该 promise 的 then 的参数,resolve 是下个 prommsie 的 resolve。实现了递归遍历数据。spa
其实通常来讲,若是真的看懂了上面的代码是不会有这个疑问的,这里并不算是发布订阅, 通常咱们发布订阅都是存一系列的 callback,一次 emit,执行全部回调,咱们这里是递归,每次执行的时候只有一个以前存好的 onFulfilled 和一个 resolve调试
这个其实得留到断点分析里去讲,由于篇幅有点长,并且我本身感受也没有彻底搞清楚,我是逆推分析出来的。code
其实为了搞懂上面那些东西,我用了差很少三天的时间,最后经过编号和打断点才搞清楚地。其实就几个问题,若是都能搞清楚,那你应该对 promise 没有任何疑问了。
答案在文中,结果在底部
最好先想一下上面的问题,若是答案不对或者没有搞很清楚,带着疑问往下看,收获会更大。生成的第几个promise就记作pro几,例如第一个promise就叫pro1。pro1的onfulfilled就是pro1的then的参数onfulfilled.
excutor(resolve)
,即执行 console.log('promiseB: resolve’)
,并触发 pro1.resolve('then1')
,步骤1结束pro1.resolve('then1')
触发, 判断传入的值是否为promise,值'then1'不是promise:pro1.value改变为pro1.resolve参数'then1',pro1状态改变,执行setTimeout里的代码,由于asyncObj为空,其实啥都不会执行,步骤2结束。proB.then...
执行,拉开了promise chain的序幕。 pro1.then(onFulfilled)
触发,返回新的promise pro2 ,判断pro1的状态,经过:执行Pro1的onFulfilled-> value=>{console.log('then1', value)return 'then2'}
,执行完毕之后获取到返回值'then2',将'then2'做为pro2.resolve的参数,即执行 pro2.resolve('then2')
,步骤3结束pro2.resolve('then2')
触发,判断传入的值是否为promise,值'then2'不是promise:pro2.value改变为pro2.resolve参数‘then2’,pro2状态改变,执行setTimeout里的代码,由于asyncObj为空,其实啥都不会执行,步骤4结束。pro2.then(onFulfilled)
触发,返回新的promise pro3 ,判断pro2的状态,经过,执行pro2的then的onfulfilled->data => { return new PromiseB((resolve) => {setTimeout(() => { console.log('非正常then2:', data) resolve('then3') }, 1000) })}
,建立并执行pro4的excutor(resolve),setTimeout(() => { console.log('非正常then2:', data) resolve('then3') }, 1000) })
,这个resolve是pro4的,获得返回值 一个promise即pro4 ,将返回值做为value传递给pro3的resolve,执行pro3.resolve(pro4)
,步骤5结束pro3.resolve(pro4)
触发,判断传入的值是否为promise,值 pro4 是promise:执行 pro4.then(pro3.resolve)
,步骤6结束。pro4.then(pro3.resolve)
触发,返回新的promise pro5,判断pro4的状态,由于状态的改变都是在this.resolve执行且参数不是promise的状况下才会改变,而pro4.resolve尚未执行,因此 不经过 :将 参数promise即pro4 的 onfulfilled即pro3的resolve 和 pro5的resolve 存起来,存到 参数promise即pro4的asyncObj 中,即此时 pro4.asyncObj={onfulfilled:pro3.resolve,resolve:pro5.resolve}
。步骤7结束,执行完毕之后继续回到promise chain,此时应该执行的是 pro3.then(onFulfilled)
pro3.then(onFulfilled)
触发(我以前的思路一直是卡在步骤7结束)。返回新的promise pro6 ,判断pro3的状态,由步骤6可知,不经过:将pro3的onFulfilled-> (value => {console.log('数据then3', value)return 'then4'})
和pro6的resolve存到pro3的asyncObj中,即此时pro3.asyncObj={onfulfilled:pro3.onFulfilled,resolve:pro6.resolve}
,返回pro6,执行 pro6.then(onFulfilled)
步骤8结束。pro6.then(onFulfilled)
触发,返回新的promise pro7 ,判断pro6的状态,和步骤7中pro4对于状态的判断一致,不经过:将pro6的onfulfilled->value=>{console.log('数据then4', value)return 'then5'}
和pro7的resolve存到pro6的asyncObj中,即此时 pro6.asyncObj={onfulfilled:pro6.onFulfilled,resolve:pro7.resolve}
,返回pro7,执行pro7.then(onFulfilled)
,步骤9结束pro7.then(onFulfilled)
触发,返回新的promise pro8 ,判断pro7的状态,和步骤7中pro4对于状态的判断一致,不经过:将pro7的onfulfilled->undefined
和pro8的resolve存到pro7的asyncObj中,即此时 pro7.asyncObj={onfulfilled:pro7.onFulfilled,resolve:pro8.resolve}
,返回pro8,执行pro8.then(onFulfilled)
,步骤10结束pro8.then(onFulfilled)
触发,返回新的promise pro9 ,判断pro8的状态,和步骤7中pro4对于状态的判断一致,不经过:将pro8的onfulfilled->value => {console.log('then5:', value) }
和pro9的resolve存到pro8的asyncObj中,即此时 pro8.asyncObj={onfulfilled:pro8.onFulfilled,resolve:pro9.resolve}
,返回pro9,由于pro9没有then,因此 没有建立新的pro10 ,promise chain的then或者说同步过程结束,执行promise chain 之后的逻辑,直到参数promise,即pro4的resolve被触发,才继续执行promise chain,步骤11结束。pro4.resolve('then3')
触发,判断传入的值是否为promise,值'then3'不是promise:pro4.value改变为pro4.resolve参数'then3',pro4状态改变,执行setTimeout里的代码,由步骤7可知 pro4.asyncObj={onfulfilled:pro3.resolve,resolve:pro5.resolve}
。先执行 let nnvalue = onfulfilled('then3')
,获得结果之后执行 pro5.resolve(nnvalue)
,onfulfilled('then3')触发,onfulfiled为pro3.resolve,即执行 pro3.resolve('then3')
,可是步骤13其实尚未结束,由于pro5.resolve(nnvalue)
尚未执行。pro3.resolve('then3')
触发,判断传入的值是否为promise,值'then3'不是promise:pro3.value改变为pro3.resolve参数'then3',pro3状态改变 ,执行setTimeout里的代码,由步骤8可知pro3.asyncObj={onfulfilled:pro3.onFulfilled,resolve:pro6.resolve}
,可是其实这里还有一步,此时进入setTimeout就是异步执行了,而在步骤13中还有一步没有执行,哪里属于主逻辑,先去执行pro5.resolve(nnvalue)
,由于let nnvalue = onfulfilled('then3')===pro3.resolve('then3')
,pro3.resolve('then3')没有返回值,因此nnvalue=undefined, pro5.resolve(undefined)
执行,判断参数undefined不是promise,修改pro5.value为undefined,修改状态,调出pro5.asyncObj,执行内部函数,由步骤7可知 pro5.then
未被调用过,因此其asyncObj为空,至此步骤13结束,可是步骤14仍在继续 ,等主流程即步骤13结束之后,步骤14setTimeout内的函数开始执行-> let nnvalue=pro3.onFulfilled('then3')-> let nnValue= (value => {console.log('数据then3', value)return 'then4'})('then3')
,获得nnvalue='then4',而后执行pro3.asyncObj.resolve(nnvalue)
即 pro6.resolve('then4')
,其实从13结束之后就开始了递归啦,步骤14结束。pro6.resolve('then4')
触发,判断参数'then4'是否为promise,不是:修改 pro4.value='then4'
,修改状态,执行定时器,等待主进程结束,执行定时器内部代码,由步骤9可得 pro6.asyncObj={onfulfilled:pro6.onFulfilled,resolve:pro7.resolve}
,pro6.onfulfilled('then4')->(value=>{console.log('数据then4', value)return 'then5'})('then4')
,而后获得结果nnvalue为 'then5', 执行 pro6.asyncObj.resolve('then5')
即 pro7.resolve('then5')
,步骤15结束pro7.resolve('then5')
触发,判断参数'then5'是否是promise,不是:修改pro7.value='then5'
,修改状态,执行定时器,等待主进程结束,执行定时器内部代码,由步骤10可得 pro7.asyncObj={onfulfilled:pro7.onFulfilled,resolve:pro8.resolve}
,由于pro7.onFulfilled=undefined,执行pro7.asyncObj.resolve('then5')
即pro8.resolve('then5')
,步骤16结束pro8.resolve('then5')
触发,判断参数'then5'是否是promise,不是:修改pro8.value='then5'
,修改状态,执行定时器,等待主进程结束,执行定时器内部代码,由步骤11可得 pro8.asyncObj={onfulfilled:pro8.onFulfilled,resolve:pro9.resolve}
,执行pro8的onfulfilled->(value => {console.log('then5:', value) })('then5')
,获得 nnvalue=undefined
执行pro8.asyncObj.resolve(undefined)
即pro9.resolve(undefined)
,步骤17结束pro9.resolve(undefined)
触发,判断参数undefined是否为promise,不是:修改pro9.value=undefined
,修改状态,执行定时器,由于pro9.then没有执行过,因此pro9.asyncObj没有值,因此结束。整个promise链也结束。