JavaScript手写Promise核心原理_第1页
JavaScript手写Promise核心原理_第2页
JavaScript手写Promise核心原理_第3页
JavaScript手写Promise核心原理_第4页
JavaScript手写Promise核心原理_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论