版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第JavaScript手写Promise核心原理目录准备完善resolve/rejectthen异步处理链式调用边界处理catch优化后完整代码
准备
首先,promise有三种状态:pendingfulfilledrejected;promise在实例化操作中,有两个改变状态的方法,分别为resolve,reject;promise有很多方法,详情请见mdn,本篇文章先实现promise的核心api:then和catch;
我们使用es6提供的class来实现
classMyPromise{
//准备三个状态
staticPENDING='pending';
staticFULFILLED='fulfilled';
staticREJECTED='rejected';
constructor(executor){
this.status=MyPromise.PENDING;//表示promise的状态
this.value=null;//表示promise的值
try{
executor(this.resolve.bind(this),this.reject.bind(this))
}catch(error){
this.reject(error)
resolve(){
reject(){
在这里executor就是传递过来的函数,可以接收resolve和reject,这里将内部的两个方法给传入,如果在调用的过程中报错了会调用reject方法
完善resolve/reject
他们做的工作分为以下几部
将状态改为pending为fulfilled或rejected可以接受一个值为当前的promise的value
resolve(value){
if(this.status===MyPromise.PENDING){
this.status=MyPromise.FULFILLED;
this.value=value
reject(value){
if(this.status===MyPromise.PENDING){
this.status=MyPromise.REJECTED;
this.value=value
then
then函数可以接受两个参数,分别为成功的回调函数和失败的回调函数,并且回调函数的默认为一个函数
状态为fulfilled执行第一个回调,rejected执行第二个回调回调函数中给传入当前的valuethen的执行为异步的
then(onFulfilled,onRejected){
if(typeofonFulfilled!=='function'){
onFulfilled=value=value
if(typeofonFulfilled!=='function'){
onRejected=value=value
if(this.status===MyPromise.FULFILLED){
setTimeout(()={
onFulfilled(this.value)
if(this.status===MyPromise.REJECTED){
setTimeout(()={
onRejected(this.value)
验证一下:
console.log(1)
newMyPromise((resolve,reject)={
console.log(2)
resolve('成功')
}).then(res=console.log(res))
console.log(3)
//打印123成功
当promise里面有异步代码的时候,这个时候运行到.then方法状态为pending,下来增加一下异步任务的处理
异步处理
当状态为pending的时候,表示执行的是异步任务,这个时候我们可以增加一个callback,把异步执行的内容添加到这个callback中,当执行完异步代码的时候,会执行异步函数的callback的任务
constructor(executor){
//...
this.callbacks=[];//用来存储回调函数的容器
//...
resolve(value){
//...
this.callbacks.forEach(({onFulfilled})=onFulfilled(value))
//当执行到这里的时候如果有onFulfilled就说明已经执行完then方法给容器添加内容了。把resolve的值传递给onFulfilled
reject(value){
//...
this.callbacks.forEach(({onRejected})=onRejected(value))
//当执行到这里的时候如果有onRejected就说明已经执行完then方法给容器添加内容了。把reject的值传递给onFulfilled
then(onFulfilled,onRejected){
//...
if(this.status===MyPromise.PENDING){
this.callbacks.push({
onFulfilled:value={
setTimeout(()={
onFulfilled(value)
onRejected:value={
setTimeout(()={
onRejected(value)
验证一下:
newMyPromise((resolve,reject)={
setTimeout(()={
resolve('成功')
}).then(res=console.log(res))
//打印成功
then函数可以链式调用,接下来我们完善一下
链式调用
链式调用的核心就是返回一个新的promise,当成功调用的时候调用新的promise的resolve,失败reject,并且链式调用会把前一个的返回值当作下一个的resolve的状态
then(onFulfilled,onRejected){
if(typeofonFulfilled!=='function'){
onFulfilled=value=value
if(typeofonFulfilled!=='function'){
onRejected=value=value
returnnewMyPromise((resolve,reject)={
if(this.status===MyPromise.FULFILLED){
setTimeout(()={
constresult=onFulfilled(this.value)
resolve(result)
if(this.status===MyPromise.REJECTED){
setTimeout(()={
constresult=onRejected(this.value)
resolve(result)
if(this.status===MyPromise.PENDING){
this.callbacks.push({
onFulfilled:value={
setTimeout(()={
constresult=onFulfilled(value)
resolve(result)
onRejected:value={
setTimeout(()={
constresult=onRejected(value)
resolve(result)
}
验证一下:
newMyPromise((resolve,reject)={
setTimeout(()={
reject('失败')
}).then(res=res,err=err).then(res=console.log(res))
//打印失败
如果.then的回调函数返回的是promise的情况也要做个处理
边界处理
实现前:
newMyPromise((resolve,reject)={
setTimeout(()={
resolve('成功')
}).then(
res=newMyPromise((resolve,reject)={
resolve(res)
err=err
).then(res=console.log(res))
//打印{"status":"fulfilled","value":"成功","callbacks":[]}
当判断返回值为MyPromise的时候,需要手动调用.then的方法取他的值,并且吧当前的promise的改变状态的函数透出给then方法
then(onFulfilled,onRejected){
if(typeofonFulfilled!=='function'){
onFulfilled=value=value
if(typeofonFulfilled!=='function'){
onRejected=value=value
returnnewMyPromise((resolve,reject)={
if(this.status===MyPromise.FULFILLED){
setTimeout(()={
constresult=onFulfilled(this.value)
if(resultinstanceofMyPromise){
result.then(resolve,reject)
}else{
resolve(result)
if(this.status===MyPromise.REJECTED){
setTimeout(()={
constresult=onRejected(this.value)
if(resultinstanceofMyPromise){
result.then(resolve,reject)
}else{
resolve(result)
if(this.status===MyPromise.PENDING){
this.callbacks.push({
onFulfilled:value={
setTimeout(()={
constresult=onFulfilled(value)
if(resultinstanceofMyPromise){
result.then(resolve,reject)
}else{
resolve(result)
onRejected:value={
setTimeout(()={
constresult=onRejected(value)
if(resultinstanceofMyPromise){
result.then(resolve,reject)
}else{
resolve(result)
验证:
newMyPromise((resolve,reject)={
setTimeout(()={
resolve('成功')
}).then(
res=newMyPromise((resolve,reject)={
resolve(res)
err=err
).then(res=console.log(res))
//打印成功
到这里.then方法就实现差不多了,接下来实现catch方法
catch
catch方法可以处理拒绝的状态和错误的状态:
catch(onFulfilled){
if(typeofonFulfilled!=='function'){
onFulfilled=value=value
returnnewMyPromise((resolve,reject)={
if(this.status===MyPromise.REJECTED){
setTimeout(()={
constresult=onFulfilled(this.value)
if(resultinstanceofMyPromise){
result.then(resolve,reject)
}else{
resolve(result)
验证:
newMyPromise((resolve,reject)={
reject('失败')
}).catch(res=console.log(res))
//打印失败
道理其实和then是相同的,到这里主功能基本上就差不多了,但是有很多重复的地方,优化一下
优化后完整代码
classMyPromise{
//准备三个状态
staticPENDING='pending';
staticFULFILLED='fulfilled';
staticREJECTED='rejected';
constructor(executor){
this.status=MyPromise.PENDING;//表示promise的状态
this.value=null;//表示promise的值
this.callbacks=[];
try{
executor(this.resolve.bind(this),this.reject.bind(this))
}catch(error){
console.log(error)
this.reject(error)
resolve(value){
if(this.status===MyPromise.PENDING){
this.status=MyPromise.FULFILLED;
this.value=value
this.callbacks.forEach(({onFulfilled})=onFulfilled(value))
reject(value){
if(this.status===MyPromise.PENDING){
this.status=MyPromise.REJECTED;
this.value=value
this.callbacks.forEach(({onRejected})=onRejected(value))
parse({callback,resolve,reject,value=this.value}){
setTimeout(()={
constresult=callback(value)
if(resultinstanceofMyPromise){
result.then(resolve,reject)
}else{
resolve(result)
then(onFulfilled,onRejected){
if(typeofonFulfilled!=='function'){
onFulfilled=value=value
if(typeofonFulfilled!=='fu
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 人体成分分析解读手册
- 淋巴引流排毒技法操作培训手册
- 客户接待咨询流程服务规范
- 农产品品牌化建设推广实施方案
- 季节性关怀服务操作规范
- 心血管风险评估操作标准
- 玉米密植高产种植实施方案
- 高血压患者低盐配餐方案
- 广东省深圳市2026年中考数学一模试卷附答案
- 身体成分检测方案执行手册
- 2025年光伏组件拆卸和更换施工技术方案
- 2025年卫生高级职称考试(心血管内科)(副高)模拟试题及答案
- 香港定居申请书
- 产品动画制作讲解
- 船员机工英语题库及答案
- DL-T+5860-2023+电化学储能电站可行性研究报告内容深度规定
- 2025年河南豫能控股股份有限公司招聘考试笔试试题含答案
- DB6108T 100-2024 一般工业固体废物矿坑回填修复治理技术规范
- 2025年国家安全部公开遴选公务员面试题及答案
- 订单应急预案管理办法
- 节能施工应急预案措施
评论
0/150
提交评论