Promise认知
promise用于异步变成的一种方式,表示一种期约/约定。有自己的状态且状态唯一,一旦改变就不可在变。 可以用来解决回调地狱的问题,也可以结合async await来实现异步代码同步化操作。
基本使用
const promise = new Promise((resolve,reject)=>{
resolve("成功");
//reject("失败");
})
promise拥有自己的状态,代表一种约定,一旦状态改变这个约定就有了结果,即状态不能再次被改变。
关于状态的改变:需要使用resolve方法来改变promise状态为成功的状态,使用reject方法来改变promise状态为失败的状态。
Promise类接收一个函数参数,可以称它为执行器,他在创建Promise对象的时候就会被调用。
/*
1.定义一个MyPromise类
2.该类有自己的状态 分别为初始化时,成功,失败,状态是固定的,可以使用定义常量的方式来定义。
2.该类接收一个立即执行的执行器函数
3.改执行器函数接收两个参数resolve与reject,这两个函数不是我们创建的,是promise自带的,所以我们要在promise里定义这两个函数
4.调用resolve方法会改吧promise状态为成功,且promise状态只能在pending时被改变,且只能改变一次,所以要判断状态为pending时才改变状态
*/
//定义状态常量
const PENDING = 'pening'//初始化状态
const FULFILLED = 'fulfilled'//成功的状态
const REJECTED = 'rejected'//失败的状态
class MyPromise{
//创建时初始化状态为pending
status = PENDING;
constructor(executor){
executor(this.resolve,this.reject)
}
//之所以写成箭头函数是因为this的指向。不清楚的可以运行一下下面的例子
resolve = ()=>{
//判断状态为初始状态才改变状态值
if(this.status === PENDING){
this.status = FULFILLED
}
}
reject = ()=>{
if(this.status === PENDING){
this.status = REJECTED
}
}
}
const promise1 = new MyPromise((resolve,reject)=>{
resolve()
})
console.log(promise1)
用箭头函数与不用箭头函数的比较,resolve用箭头函数写,reject用普通函数写,比较两者
const PENDING = 'pening'//初始化状态
const FULFILLED = 'fulfilled'//成功的状态
const REJECTED = 'rejected'//失败的状态
class MyPromise{
//创建时初始化状态为pending
status = PENDING;
constructor(executor){
executor(this.resolve,this.reject)
}
//之所以写成箭头函数是因为this的指向。不清楚的可以运行一下下面的例子
resolve = ()=>{
//判断状态为初始状态才改变状态值
if(this.status === PENDING){
this.status = FULFILLED
}
}
reject = function{
if(this.status === PENDING){
this.status = REJECTED
}
}
}
const promise1 = new MyPromise((resolve,reject)=>{
resolve()
})
console.log("箭头函数",promise1)
const promise2 = new MyPromise((resolve,reject)=>{
reject()
})
console.log("普通函数",promise1)
得到如下结果,正常打印箭头函数,普通函数会报错。因为是this的指向问题。箭头函数没有自身的this,它的this是他上层函数的this,且在创建时已经确定,如果是普通函数,他是this在调用的时候确定,而我们使用resolve和reject的时候是直接调用的他的this为undefined,所以会报错。
创建的promise对象的状态改变之后就会触发相应的then方法。
const promise = new Promise((resolve,reject)=>{
resolve("成功");
//reject("失败");
})
promise.then(value=>{
console.log("成功的状态:",value)
},reason=>{
console.log("失败的原因:",reason)
})
promise对象状态改变之后触发相应的then方法,也就是promise实例有then方法。这个方法接受两个外部传入的函数,来处理相应的成功/失败的逻辑。
const PENDING = 'pening'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
status = PENDING;
//初始化value与reason
value = undefined;
reason = undefined;
constructor(executor){
executor(this.resolve,this.reject)
}
resolve = (value)=>{
if(this.status === PENDING){
this.status = FULFILLED;
//成功则改变value为传入的值
this.value = value;
}
}
reject = (reason)=>{
if(this.status === PENDING){
//失败则改变reason 为传入的值
this.status = REJECTED;
this.reason =reason;
}
}
//为primose实例新增then方法,接受两个函数参数/分布来处理相应的成功/失败的逻辑。
//必须在相应的状态执行相应的逻辑
//成功的状态调用传入的第一个函数参数,此函数参数的参数为修改状态为成功时调用的resolve方法传入的参数this.value
//失败的状态调用传入的第二个函数参数,此函数参数的参数为修改状态为失败时调用的reject方法传入的参数this.reason
then = (fulfilled,rejected)=>{
if(this.status === FULFILLED){
fulfilled(this.value)
}
else if(this.status === REJECTED){
rejected(this.reason)
}
}
}
const promise1 = new MyPromise((resolve,reject)=>{
resolve()
})
promise1.then(value=>{
console.log("成功状态:",value)
},reason=>{
console.log("失败状态:",reason)
})
异步逻辑
JS代码的运行分为同步任务与异步任务。上面定义的myPromise运行同步代码是没有问题的,当创建一个新的promise对象时,直接改变了他的状态,在接下来使用此promise的then方法,此处状态已经改变,所以会按照他的状态执行接下来的流程。但是如果创建promise时改变promise状态的操作是异步的,如使用定时器在几秒之后再改变promise的状态,此时执行到then方法时,状态还是pending状态,而上面定义的myPromise并没有在状态为pending时的处理逻辑。所以我们应该为状态为pending时添加相应的处理逻辑。看下面的代码。
//沿用上面定义的MyPromise
const promise = new MyPromise((resolve,reject)=>{
setTimeout(()=>{
resolve("延迟2s改变状态")
},2000)
})
promise.then(value=>{
console.log(value)
},reason=>{
console.log(reason)
})
/*
创建了一个promise对象。执行器中有setTimeout会把定时器中的逻辑加入异步队列。
继续执行promise对象的then方法,此时promise的状态为pending不会进行任何操作。
同步代码执行完毕,检查异步对列,发现有一个,则在时间到达时执行异步逻辑,设置promise的状态为成功的状态。所以上面的代码不会有任何输出。
经过上面的分析,问题出在执行then方法时,promise的状态还没有改变,所以不会进行任何操作。我们要做的就是,如果在执行then方法时promise的状态为pending,则把相应的逻辑存储起来,等到状态改变时执行相应的逻辑。
*/
修改MyPromise代码如下
const PENDING = 'pening'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
status = PENDING;
value = undefined;
reason = undefined;
//初始化then传入的成功时缓存的相关逻辑
fulfilledCallback = undefined;
//初始化then传入的失败时缓存的相关逻辑
rejectedCallback = undefined;
constructor(executor){
executor(this.resolve,this.reject)
}
resolve = (value)=>{
if(this.status === PENDING){
this.status = FULFILLED;
this.value = value;
//状态改变为成功时时,如果有缓存的成功状态的相关逻辑,则执行
this.fulfilledCallback && this.fulfilledCallback(this.value)
}
}
reject = (reason)=>{
if(this.status === PENDING){
this.status = REJECTED;
this.reason =reason;
//状态改变为失败时,如果有缓存的失败状态的相关逻辑,则执行
this.rejectedCallback && this.rejectedCallback(this.reason)
}
}
then = (fulfilled,rejected)=>{
if(this.status === FULFILLED){
fulfilled(this.value)
}
else if(this.status === REJECTED){
rejected(this.reason)
}
//如果状态为pending则存储then传入的执行逻辑
else{
this.fulfilledCallback = fulfilled;
this.rejectedCallback =rejected;
}
}
}
const promise1 = new MyPromise((resolve,reject)=>{
setTimeout(()=>{
resolve("延迟2秒改变状态为成功")
},2000)
})
promise1.then(value=>{
console.log("成功状态:",value)
},reason=>{
console.log("失败状态:",reason)
})
多次调用then方法
同一个promise对象是可以多次调用then方法的,不管调用多少次then方法,在状态已经改变的请求下。都会按照状态来执行相关逻辑。但是如果是异步逻辑,多次调用then方法时,promise状态还没有改变,按照我们上面的代码,直接对fulfilledCallback或者是rejectedCallback进行赋值的话,就只会执行最后一次的逻辑。而每一次then方法的逻辑都应该在状态改变之后执行,也就是说需要存储多个函数,并且在状态改变之后执行。改写myPromise代码如下。
const PENDING = 'pening'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
status = PENDING;
value = undefined;
reason = undefined;
//可能会有多个逻辑,所以改写为数组类型
fulfilledCallback = [];
rejectedCallback = [];
constructor(executor){
executor(this.resolve,this.reject)
}
resolve = (value)=>{
if(this.status === PENDING){
this.status = FULFILLED;
this.value = value;
//执行成功状态数组中的每一个函数,执行顺序为第一个先执行。
while(this.fulfilledCallback.length){
//用shift方法从最前面开始取函数执行
this.fulfilledCallback.shift()(this.value)
}
}
}
reject = (reason)=>{
if(this.status === PENDING){
this.status = REJECTED;
this.reason =reason;
//执行失败状态数组中的每一个函数,执行顺序为第一个先执行。
while(this.rejectedCallback.length){
//用shift方法从最前面开始取函数执行
this.rejectedCallback.shift()(this.reason)
}
}
}
then = (fulfilled,rejected)=>{
if(this.status === FULFILLED){
fulfilled(this.value)
}
else if(this.status === REJECTED){
rejected(this.reason)
}
//如果状态为pending则给相关数组加入相关函数
else{
this.fulfilledCallback.push(fulfilled);
this.rejectedCallback.push(rejected);
}
}
}
const promise1 = new MyPromise((resolve,reject)=>{
setTimeout(()=>{
resolve("延迟2秒改变状态为成功")
},2000)
})
promise1.then(value=>{
console.log("成功状态1:",value)
},reason=>{
console.log("失败状态1:",reason)
})
promise1.then(value=>{
console.log("成功状态2:",value)
},reason=>{
console.log("失败状态2:",reason)
})
promise1.then(value=>{
console.log("成功状态3:",value)
},reason=>{
console.log("失败状态3:",reason)
})
then方法的链式调用
then方法可以链式调用,链式调用的基本使用
const promise = new Promise((resolve,reject)=>{
resolve("第一次链式调用")
})
promise.then(value=>{
console.log(value)
return "第二次链式调用"
}).then(value=>{
console.log(value)
})
//打印第一次链式调用
//第二次链式调用
从上面代码可以看出,then可以进行链式调用,那么then应该返回一个promise对象。且该promise对象的then方法传入的成功的回调与失败的回调的参数是上一个then方法的返回值。
const PENDING = 'pening'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
status = PENDING;
value = undefined;
reason = undefined;
fulfilledCallback = [];
rejectedCallback = [];
constructor(executor){
executor(this.resolve,this.reject)
}
resolve = (value)=>{
if(this.status === PENDING){
this.status = FULFILLED;
this.value = value;
while(this.fulfilledCallback.length){
this.fulfilledCallback.shift()(this.value)
}
}
}
reject = (reason)=>{
if(this.status === PENDING){
this.status = REJECTED;
this.reason =reason;
while(this.rejectedCallback.length){
this.rejectedCallback.shift()(this.reason)
}
}
}
then = (fulfilled,rejected)=>{
//then方法需要返回一个promise对象
const promise2 = new MyPromise((resolve,reject)=>{
if(this.status === FULFILLED){
//接受返回值,作为下一次then的参数
const x = fulfilled(this.value)
resolve(x)
}
else if(this.status === REJECTED){
rejected(this.reason)
}
else{
this.fulfilledCallback.push(fulfilled);
this.rejectedCallback.push(rejected);
}
})
return promise2
}
}
const promise1 = new MyPromise((resolve,reject)=>{
resolve("第一次链式调用")
})
promise1.then(value=>{
console.log(value)
return "第二次链式调用"
}).then(value=>{
console.log(value)
})
then方法不止可以返回普通的数据,还可能返回promise对象,更加返回类型不同需要做不同的处理,如果返回的是一个普通的值,则直接调用resolve方法,传递返回值即可。如果是promise对象则要根据promise对象的状态来确定是调用resolve还是reject方法。
const PENDING = 'pening'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
status = PENDING;
value = undefined;
reason = undefined;
fulfilledCallback = [];
rejectedCallback = [];
constructor(executor){
executor(this.resolve,this.reject)
}
resolve = (value)=>{
if(this.status === PENDING){
this.status = FULFILLED;
this.value = value;
while(this.fulfilledCallback.length){
this.fulfilledCallback.shift()(this.value)
}
}
}
reject = (reason)=>{
if(this.status === PENDING){
this.status = REJECTED;
this.reason =reason;
while(this.rejectedCallback.length){
this.rejectedCallback.shift()(this.reason)
}
}
}
then = (fulfilled,rejected)=>{
//then方法需要返回一个promise对象
const promise2 = new MyPromise((resolve,reject)=>{
if(this.status === FULFILLED){
//接受返回值,作为下一次then的参数
const x = fulfilled(this.value)
//判断返回值类型做不同的处理,多个地方要使用,所以封装成一个函数
resolvePromise(x,resolve,reject)
}
else if(this.status === REJECTED){
rejected(this.reason)
}
else{
this.fulfilledCallback.push(fulfilled);
this.rejectedCallback.push(rejected);
}
})
return promise2
}
}
function resolvePromise(x,resolve,reject){
//判断x的值,如果是普通值则直接resolve,promise类型的值则根据promise状态确定调用哪个方法
if(x instanceof MyPromise){
x.then(value=>resolve(value),reason=>reject(reason))
}
else{
resolve(x)
}
}
const promise1 = new MyPromise((resolve,reject)=>{
resolve("第一次链式调用")
})
promise1.then(value=>{
console.log(value)
return new MyPromise((resolve,reject)=>{
resolve("返回一个promsie对象")
})
}).then(value=>{
console.log(value)
})
then方法返回的promise对象不能是他执行完毕之后返回的promise对象,否则会发生循环引用。
const promise = new Promise((resolve,reject)=>{
resolve("第一次调用")
})
const promise1 = promise.then(value=>{
console.log(value)
return promise1
})
//第一次调用
// UnhandledPromiseRejectionWarning: TypeError: Chaining cycle detected for promise #<Promise>
像上面这样就会出现循环引用报错。改写MyPromise
const PENDING = 'pening'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
status = PENDING;
value = undefined;
reason = undefined;
fulfilledCallback = [];
rejectedCallback = [];
constructor(executor){
executor(this.resolve,this.reject)
}
resolve = (value)=>{
if(this.status === PENDING){
this.status = FULFILLED;
this.value = value;
while(this.fulfilledCallback.length){
this.fulfilledCallback.shift()(this.value)
}
}
}
reject = (reason)=>{
if(this.status === PENDING){
this.status = REJECTED;
this.reason =reason;
while(this.rejectedCallback.length){
this.rejectedCallback.shift()(this.reason)
}
}
}
then = (fulfilled,rejected)=>{
const promise2 = new MyPromise((resolve,reject)=>{
if(this.status === FULFILLED){
//需要判断promise2与x是不是同一个对象,同一对象则会循环引用
//promise2会在函数执行完毕之后才会创建,要想在这里使用,需要使用异步任务
setTimeout(()=>{
const x = fulfilled(this.value)
resolvePromise(promise2,x,reslove,reject)
},0)
}
else if(this.status === REJECTED){
rejected(this.reason)
}
else{
this.fulfilledCallback.push(fulfilled);
this.rejectedCallback.push(rejected);
}
})
return promise2
}
}
function resolvePromise(promise2,x,resolve,reject){
//相同则reject给一个类型错误信息
if(promise2 === x){
return reject(new TypeError("Chaining cycle detected for promise #<Promise>"))
}
if(x instanceof MyPromise){
x.then(value=>resolve(value),reason=>reject(reason))
}
else{
resolve(x)
}
}
const promise1 = new MyPromise((resolve,reject)=>{
resolve("第一次链式调用")
})
const promise2 = promise1.then(value=>{
console.log(value)
return promise2
})
promise2.then(value=>{},reason=>{
console.log(reason)
})
错误处理及失败状态代码补全
在代码执行过程中,是可能会发生错误的,当错误出现的时候我们要捕获这个错误,并且把promise的状态设置为reject。
可能发生错误的地方有执行器执行的时候,then方法调用的时候。
const PENDING = 'pening'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
status = PENDING;
value = undefined;
reason = undefined;
fulfilledCallback = [];
rejectedCallback = [];
constructor(executor){
//如果执行器出现错误,则改变状态为reject
try{
executor(this.resolve,this.reject)
}
catch(err){
this.reject(err)
}
}
resolve = (value)=>{
if(this.status === PENDING){
this.status = FULFILLED;
this.value = value;
while(this.fulfilledCallback.length){
//下面改写之后传递了参数,这里不用再传
this.fulfilledCallback.shift()()
}
}
}
reject = (reason)=>{
if(this.status === PENDING){
this.status = REJECTED;
this.reason =reason;
while(this.rejectedCallback.length){
//下面改写之后传递了参数,这里不用再传
this.rejectedCallback.shift()()
}
}
}
then = (fulfilled,rejected)=>{
const promise2 = new MyPromise((resolve,reject)=>{
if(this.status === FULFILLED){
//需要判断promise2与x是不是同一个对象,同一对象则会循环引用
//promise2会在函数执行完毕之后才会创建,要想在这里使用,需要使用异步任务
setTimeout(()=>{
//执行fulfilled时出现错误也要吧状态改为reject,给后面的then使用
try{
const x = fulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
}
else if(this.status === REJECTED){
//参照成功状态补全失败状态代码
//需要判断promise2与x是不是同一个对象,同一对象则会循环引用
//promise2会在函数执行完毕之后才会创建,要想在这里使用,需要使用异步任务
setTimeout(()=>{
//执行fulfilled时出现错误也要吧状态改为reject,给后面的then使用
try{
const x = rejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
}
else{
//参照成功状态进行改下存储的函数
this.fulfilledCallback.push(()=>{
setTimeout(()=>{
//执行fulfilled时出现错误也要吧状态改为reject,给后面的then使用
try{
const x = fulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
})
this.rejectedCallback.push(()=>{
setTimeout(()=>{
//执行fulfilled时出现错误也要吧状态改为reject,给后面的then使用
try{
const x = rejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
});
}
})
return promise2
}
}
function resolvePromise(promise2,x,resolve,reject){
if(promise2 === x){
return reject(new TypeError("Chaining cycle detected for promise #<Promise>"))
}
if(x instanceof MyPromise){
x.then(value=>resolve(value),reason=>reject(reason))
}
else{
resolve(x)
}
}
const promise1 = new MyPromise((resolve,reject)=>{
setTimeout(() => {
resolve("成功")
}, 2000);
})
promise1.then(value=>{
console.log(value)
return "返回一个普通值"
}).then(value=>{
console.log(value)
})
将then方法参数变为可选参数
promise中如果then方法没有传参,那么他的状态是可以原样向后传递的,如
const promise = new Promise(resolve,reject=>{
reject("成功")
})
promise.then().then().then(value=>{
console.log(value)
})
//最后会打印成功
//等同于下面的代码
promise.then(value=>value).then(value=>value).then(value=>{
console.log(value)
})
判断then方法参数是否存在
const PENDING = 'pening'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
status = PENDING;
value = undefined;
reason = undefined;
fulfilledCallback = [];
rejectedCallback = [];
constructor(executor){
//如果执行器出现错误,则改变状态为reject
try{
executor(this.resolve,this.reject)
}
catch(err){
this.reject(err)
}
}
resolve = (value)=>{
if(this.status === PENDING){
this.status = FULFILLED;
this.value = value;
while(this.fulfilledCallback.length){
//下面改写之后传递了参数,这里不用再传
this.fulfilledCallback.shift()()
}
}
}
reject = (reason)=>{
if(this.status === PENDING){
this.status = REJECTED;
this.reason =reason;
while(this.rejectedCallback.length){
//下面改写之后传递了参数,这里不用再传
this.rejectedCallback.shift()()
}
}
}
then = (fulfilled,rejected)=>{
//需要判断fulfilled与rejected是否存在,存在则进行之前的逻辑,不存在的话给他一个默认函数
fulfilled = fulfilled ? fulfilled :value=>value;
//用throw才能改变状态为失败。用来传递错误
rejected = rejected ? rejected :reason=>{throw reason};
const promise2 = new MyPromise((resolve,reject)=>{
if(this.status === FULFILLED){
setTimeout(()=>{
try{
const x = fulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
}
else if(this.status === REJECTED){
setTimeout(()=>{
try{
const x = rejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
}
else{
this.fulfilledCallback.push(()=>{
setTimeout(()=>{
try{
const x = fulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
})
this.rejectedCallback.push(()=>{
setTimeout(()=>{
try{
const x = rejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
});
}
})
return promise2
}
}
function resolvePromise(promise2,x,resolve,reject){
if(promise2 === x){
return reject(new TypeError("Chaining cycle detected for promise #<Promise>"))
}
if(x instanceof MyPromise){
x.then(value=>resolve(value),reason=>reject(reason))
}
else{
resolve(x)
}
}
const promise1 = new MyPromise((resolve,reject)=>{
resolve("成功")
})
promise1.then().then().then(value=>{
console.log(value)
})
Promise.all
Promise.all可以同时执行多个promise,返回一个promise对象,只有当所有的promise的状态为成功的状态,他的状态才为成功,接受到的成功的数据为一个数组,结果数组顺序和传入promise的顺序一致,有一个失败则为失败的状态,且失败的原因为失败的promise的原因。
const PENDING = 'pening'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
status = PENDING;
value = undefined;
reason = undefined;
fulfilledCallback = [];
rejectedCallback = [];
//all通过类名直接调用,所以他是一个静态方法,接受一个数组,数组元素可以使普通数据也可以是promise对象
static all(arr){
//定义一个结果数组来存储获得数据
return new MyPromise((resolve,reject)=>{
let result = [];
//如果遇到异步任务,forEach会先执行完毕,如果直接resolve的话,会造成异步任务结果为空,只有等待所有promise都拿到了结果且放进result数组之后才能进行resolve。定义一个变量来检查是否全部添加完成。
let resultIndex = 0;
//遍历拿到所有的数组元素
arr.forEach((item,index)=>{
//如果是普通数据,则直接得到这个数据,如果是promise对象则要根据对象状态来确定操作
if(item instanceof MyPromise){
//成功状态把成功的值给结果数组,失败则状态改变为失败,传递失败的原因
item.then(value=>{
result[index] = value;
resultIndex++;
//已添加的数量等于传入的数量时才改变状态
if(resultIndex === arr.length){
resolve(result)
}
},reason=>reject(reason))
}
else{
result[index] = item;
resultIndex++;
//已添加的数量等于传入的数量时才改变状态
if(resultIndex === arr.length){
resolve(result)
}
}
})
})
}
constructor(executor){
try{
executor(this.resolve,this.reject)
}
catch(err){
this.reject(err)
}
}
resolve = (value)=>{
if(this.status === PENDING){
this.status = FULFILLED;
this.value = value;
while(this.fulfilledCallback.length){
this.fulfilledCallback.shift()()
}
}
}
reject = (reason)=>{
if(this.status === PENDING){
this.status = REJECTED;
this.reason =reason;
while(this.rejectedCallback.length){
this.rejectedCallback.shift()()
}
}
}
then = (fulfilled,rejected)=>{
fulfilled = fulfilled ? fulfilled :value=>value;
rejected = rejected ? rejected :reason=>{throw reason};
const promise2 = new MyPromise((resolve,reject)=>{
if(this.status === FULFILLED){
setTimeout(()=>{
try{
const x = fulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
}
else if(this.status === REJECTED){
setTimeout(()=>{
try{
const x = rejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
}
else{
this.fulfilledCallback.push(()=>{
setTimeout(()=>{
try{
const x = fulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
})
this.rejectedCallback.push(()=>{
setTimeout(()=>{
try{
const x = rejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
});
}
})
return promise2
}
}
function resolvePromise(promise2,x,resolve,reject){
if(promise2 === x){
return reject(new TypeError("Chaining cycle detected for promise #<Promise>"))
}
if(x instanceof MyPromise){
x.then(value=>resolve(value),reason=>reject(reason))
}
else{
resolve(x)
}
}
function p1(){
return new MyPromise((resolve,reject)=>{
setTimeout(()=>{
resolve('p1')
},2000)
})
}
function p2(){
return new MyPromise((resolve,reject)=>{
resolve('p2')
})
}
MyPromise.all(['a','b',p1(),p2(),'c']).then(value=>{
console.log(value)
})
Promise.resolve
Promise.resolve会将接受到的数字转换为一个promise对象返回,如果传入的就是一个promise对象则会原封不动的返回
const PENDING = 'pening'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
status = PENDING;
value = undefined;
reason = undefined;
fulfilledCallback = [];
rejectedCallback = [];
static resolve(value){
//判断data的类型,如果是promise类型的则原封不动的返回
if(value instanceof MyPromise){
return value
}
//如果是普通类型的则转换为promise对象返回
else{
return new MyPromise((resolve,reject)=>{
resolve(value)
})
}
}
static all(arr){
return new MyPromise((resolve,reject)=>{
let result = [];
let resultIndex = 0;
arr.forEach((item,index)=>{
if(item instanceof MyPromise){
item.then(value=>{
result[index] = value;
resultIndex++;
if(resultIndex === arr.length){
resolve(result)
}
},reason=>reject(reason))
}
else{
result[index] = item;
resultIndex++;
if(resultIndex === arr.length){
resolve(result)
}
}
})
})
}
constructor(executor){
try{
executor(this.resolve,this.reject)
}
catch(err){
this.reject(err)
}
}
resolve = (value)=>{
if(this.status === PENDING){
this.status = FULFILLED;
this.value = value;
while(this.fulfilledCallback.length){
this.fulfilledCallback.shift()()
}
}
}
reject = (reason)=>{
if(this.status === PENDING){
this.status = REJECTED;
this.reason =reason;
while(this.rejectedCallback.length){
this.rejectedCallback.shift()()
}
}
}
then = (fulfilled,rejected)=>{
fulfilled = fulfilled ? fulfilled :value=>value;
rejected = rejected ? rejected :reason=>{throw reason};
const promise2 = new MyPromise((resolve,reject)=>{
if(this.status === FULFILLED){
setTimeout(()=>{
try{
const x = fulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
}
else if(this.status === REJECTED){
setTimeout(()=>{
try{
const x = rejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
}
else{
this.fulfilledCallback.push(()=>{
setTimeout(()=>{
try{
const x = fulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
})
this.rejectedCallback.push(()=>{
setTimeout(()=>{
try{
const x = rejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
});
}
})
return promise2
}
}
function resolvePromise(promise2,x,resolve,reject){
if(promise2 === x){
return reject(new TypeError("Chaining cycle detected for promise #<Promise>"))
}
if(x instanceof MyPromise){
x.then(value=>resolve(value),reason=>reject(reason))
}
else{
resolve(x)
}
}
function p1(){
return new MyPromise((resolve,reject)=>{
setTimeout(()=>{
resolve('p1')
},2000)
})
}
function p2(){
return new MyPromise((resolve,reject)=>{
resolve('p2')
})
}
MyPromise.resolve('a').then(value=>{
console.log(value)
})
MyPromise.resolve(p1()).then(value=>{
console.log(value)
})
finally方法
无论promise的状态如何finally中的代码都会执行,他接受一个函数参数。返回一个promise对象。
const PENDING = 'pening'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
status = PENDING;
value = undefined;
reason = undefined;
fulfilledCallback = [];
rejectedCallback = [];
static resolve(data){
//判断data的类型,如果是promise类型的则原封不动的返回
if(data instanceof MyPromise){
return data
}
//如果是普通类型的则转换为promise对象返回
else{
return new MyPromise((resolve,reject)=>{
resolve(data)
})
}
}
static all(arr){
return new MyPromise((resolve,reject)=>{
let result = [];
let resultIndex = 0;
arr.forEach((item,index)=>{
if(item instanceof MyPromise){
item.then(value=>{
result[index] = value;
resultIndex++;
if(resultIndex === arr.length){
resolve(result)
}
},reason=>reject(reason))
}
else{
result[index] = item;
resultIndex++;
if(resultIndex === arr.length){
resolve(result)
}
}
})
})
}
finally = (callback)=>{
//无论什么样的状态都要执行回调函数,借助then方法在成功和失败的回调中都调用callback
//finally返回一个promise对象,该对象的状态为调用finally的对象的状态,其实就是then方法的返回值。
return this.then(value=>{
// callback()
// //传递给下一个then方法的参数为then方法相应状态的参数
// return value
//如果遇到异步任务,需要等到异步结果再把结果返回回去,可以借助上面写的resolve方法,讲callback得结果转为promise对象,在状态改变之后返回回去
return MyPromise.resolve(callback()).then(()=>value)
},reason=>{
// callback()
// //传递给下一个then方法的参数为then方法相应状态的参数,失败状态需要通过throw改变状态为reject。
// throw reason
//如果遇到异步任务,需要等到异步结果再把结果返回回去,可以借助上面写的resolve方法,讲callback得结果转为promise对象,在状态改变之后返回回去
return MyPromise.resolve(callback()).then(()=>{throw reason})
})
}
constructor(executor){
try{
executor(this.resolve,this.reject)
}
catch(err){
this.reject(err)
}
}
resolve = (value)=>{
if(this.status === PENDING){
this.status = FULFILLED;
this.value = value;
while(this.fulfilledCallback.length){
this.fulfilledCallback.shift()()
}
}
}
reject = (reason)=>{
if(this.status === PENDING){
this.status = REJECTED;
this.reason =reason;
while(this.rejectedCallback.length){
this.rejectedCallback.shift()()
}
}
}
then = (fulfilled,rejected)=>{
fulfilled = fulfilled ? fulfilled :value=>value;
rejected = rejected ? rejected :reason=>{throw reason};
const promise2 = new MyPromise((resolve,reject)=>{
if(this.status === FULFILLED){
setTimeout(()=>{
try{
const x = fulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
}
else if(this.status === REJECTED){
setTimeout(()=>{
try{
const x = rejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
}
else{
this.fulfilledCallback.push(()=>{
setTimeout(()=>{
try{
const x = fulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
})
this.rejectedCallback.push(()=>{
setTimeout(()=>{
try{
const x = rejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
});
}
})
return promise2
}
}
function resolvePromise(promise2,x,resolve,reject){
if(promise2 === x){
return reject(new TypeError("Chaining cycle detected for promise #<Promise>"))
}
if(x instanceof MyPromise){
x.then(value=>resolve(value),reason=>reject(reason))
}
else{
resolve(x)
}
}
function p1(){
return new MyPromise((resolve,reject)=>{
setTimeout(()=>{
resolve('p1')
},2000)
})
}
function p2(){
return new MyPromise((resolve,reject)=>{
resolve('p2')
})
}
const promise1 = new MyPromise((resolve,rejct)=>{
resolve(1)
}).finally(()=>{
console.log("finally执行了")
return p1()
}).then(value=>{
console.log(value)
})
catch方法
catch方法接受一个失败的处理回调函数,用于失败状态的处理操作,并且可以继续使用then方法,所以他的返回值为promise对象
const PENDING = 'pening'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
status = PENDING;
value = undefined;
reason = undefined;
fulfilledCallback = [];
rejectedCallback = [];
static resolve(data){
//判断data的类型,如果是promise类型的则原封不动的返回
if(data instanceof MyPromise){
return data
}
//如果是普通类型的则转换为promise对象返回
else{
return new MyPromise((resolve,reject)=>{
resolve(data)
})
}
}
static all(arr){
return new MyPromise((resolve,reject)=>{
let result = [];
let resultIndex = 0;
arr.forEach((item,index)=>{
if(item instanceof MyPromise){
item.then(value=>{
result[index] = value;
resultIndex++;
if(resultIndex === arr.length){
resolve(result)
}
},reason=>reject(reason))
}
else{
result[index] = item;
resultIndex++;
if(resultIndex === arr.length){
resolve(result)
}
}
})
})
}
finally = (callback)=>{
return this.then(value=>{
return MyPromise.resolve(callback()).then(()=>value)
},reason=>{
return MyPromise.resolve(callback()).then(()=>{throw reason})
})
}
catch = (fallBack)=>{
//调catch方法会执行失败的操作,返回promise对象。
return this.then(undefined,fallBack)
}
constructor(executor){
try{
executor(this.resolve,this.reject)
}
catch(err){
this.reject(err)
}
}
resolve = (value)=>{
if(this.status === PENDING){
this.status = FULFILLED;
this.value = value;
while(this.fulfilledCallback.length){
this.fulfilledCallback.shift()()
}
}
}
reject = (reason)=>{
if(this.status === PENDING){
this.status = REJECTED;
this.reason =reason;
while(this.rejectedCallback.length){
this.rejectedCallback.shift()()
}
}
}
then = (fulfilled,rejected)=>{
fulfilled = fulfilled ? fulfilled :value=>value;
rejected = rejected ? rejected :reason=>{throw reason};
const promise2 = new MyPromise((resolve,reject)=>{
if(this.status === FULFILLED){
setTimeout(()=>{
try{
const x = fulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
}
else if(this.status === REJECTED){
setTimeout(()=>{
try{
const x = rejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
}
else{
this.fulfilledCallback.push(()=>{
setTimeout(()=>{
try{
const x = fulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
})
this.rejectedCallback.push(()=>{
setTimeout(()=>{
try{
const x = rejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
}
catch(err){
reject(err)
}
},0)
});
}
})
return promise2
}
}
function resolvePromise(promise2,x,resolve,reject){
if(promise2 === x){
return reject(new TypeError("Chaining cycle detected for promise #<Promise>"))
}
if(x instanceof MyPromise){
x.then(value=>resolve(value),reason=>reject(reason))
}
else{
resolve(x)
}
}