JS手写一个自定义Promise操作示例
本文实例讲述了JS手写一个自定义Promise操作。分享给大家供大家参考,具体如下:
经常在面试题中会看到,让你实现一个Promsie,或者问你实现Promise的原理,所以今天就尝试利用class类的形式来实现一个Promise
为了不与原生的Promise命名冲突,这里就简单命名为MyPromise.
classMyPromise{
constructor(executor){
let_this=this
this.state='pending'//当前状态
this.value=undefined//存储成功的值
this.reason=undefined//存储失败的值
//利用发布订阅模式,让Promise支持异步
this.onFulfilledFunc=[]//存储成功的回调
this.onRejectedFunc=[]//存储失败的回调
functionresolve(value){
//Promise对象已经由pending状态改变为了成功态(resolved)或是失败态(rejected)就不能再次更改状态了。因此我们在更新状态时要判断,如果当前状态是pending(等待态)才可更新
if(_this.state==='pending'){
_this.value=value
//依次执行成功回调
_this.onFulfilledFunc.forEach(fn=>fn(value))
_this.state='resolved'
}
}
functionreject(reason){
//Promise对象已经由pending状态改变为了成功态(resolved)或是失败态(rejected)就不能再次更改状态了。因此我们在更新状态时要判断,如果当前状态是pending(等待态)才可更新
if(_this.state==='pending'){
_this.reason=reason
//依次执行失败回调
_this.onRejectedFunc.forEach(fn=>fn(reason))
_this.state='rejected'
}
}
try{
//当实例化Promise时,构造函数中就要马上调用传入的executor函数执行
executor(resolve,reject)
}catch(error){
reject(error)
}
}
_resolvePromise(promise2,x,resolve,reject){
//如果返回了自己的Promise对象,状态永远为等待态(pending),再也无法成为resolved或是rejected,程序会死掉,因此首先要处理它
if(promise2===x){
reject(newTypeError('Promise存在循环引用'))
}
if(x!==null&&(typeofx==='object'||typeofx==='function')){
//x可能是一个promise
try{
letthen=x.then
if(typeofthen==='function'){
then.call(x,(y)=>{
_resolvePromise(promise2,y,resolve,reject)
})
}else{
resolve(x)
}
}catch(err){
reject(err)
}
}else{
//否则是个普通值
resolve(x)
}
}
then(onFulfilled,onRejected){
letpromise2
onFulfilled=typeofonFulfilled==='function'?onFulfilled:function(val){returnval}
onRejected=typeofonRejected==='function'?onRejected:function(reason){throwreason}
if(this.state==='resolved'){
promise2=newMyPromise((resolve,reject)=>{
setTimeout(()=>{
try{
letx=onFulfilled(this.value)
this._resolvePromise(promise2,x,resolve,reject)
}catch(error){
reject(error)
}
},0);
})
}
if(this.state==='rejected'){
promise2=newMyPromise((resolve,reject)=>{
setTimeout(()=>{
try{
letx=onRejected(this.reason)
this._resolvePromise(promise2,x,resolve,reject)
}catch(error){
reject(error)
}
},0);
})
}
if(this.state==='pending'){
promise2=newMyPromise((resolve,reject)=>{
this.onFulfilledFunc.push(()=>{
setTimeout(()=>{
try{
letx=onFulfilled(this.value)
this._resolvePromise(promise2,x,resolve,reject)
}catch(error){
reject(error)
}
},0);
})
this.onRejectedFunc.push(()=>{
setTimeout(()=>{
try{
letx=onRejected(this.reason)
this._resolvePromise(promise2,x,resolve,reject)
}catch(error){
reject(error)
}
},0);
})
})
}
returnpromise2
}
}
运行测试:
varpromise=newMyPromise((resolve,reject)=>{
console.log(1)
setTimeout(()=>{
resolve(2)
},1000);
console.log(3)
}).then(value=>console.log(value))
结果真香:
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。