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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。