代码:
源码文件:MyPromise.js
const PENDING = 'pending' //等待状态
const FULFILLED = 'fulfilled'//成功状态
const REJECTED = 'rejected'//失败状态
class MyPromise {
constructor(exector) {
//执行器
//创建peromise的时候传入的执行器会立刻执行
exector(this.resolve, this.reject)//传递进来两个函数,一个是成功的函数,一个失败的函数
}
status = PENDING;//设置默认的状态为等待状态
value = undefined //设置一开始传递进来的成功的值为undefined
reason = undefined //设置一开始传递进来的失败的值为undefined
resolve = (value) => {
//value为传递进来的成功的值
//用来改变状态,把状态变为成功
if(this.status !== PENDING) return //因为状态是不可逆的,所以我们要在这里判断一下,以防更改状态
this.status = FULFILLED
this.value = value // 把传递进来的成功的值赋值
}
reject = (reason) => {
//reason为传递进来的失败的原因
//用来改变状态,把状态变为失败
if(this.status !== PENDING) return //因为状态是不可逆的,所以我们要在这里判断一下,以防更改状态
this.status = REJECTED
this.reason = reason// 把传递进来的失败的原因赋值
}
then=(fulfilledCallBack,rejectedCallBack)=>{
//then方法中有两个回调函数一个成功的fulfilledCallBack,一个失败的rejectedCallBack
if(this.status === FULFILLED) {
fulfilledCallBack(this.value)//将成功的值传给成功的回调函数
}else if(this.status === REJECTED){
rejectedCallBack(this.reason)//将失败的值传给失败的回调函数
}
}
}
module.exports = MyPromise
测试文件:testPromise.js
const MyPromise = require('./myPromise')
const promise = new MyPromise((resolve,reject)=>{
resolve("成功拉")
//reject("失败")
})
promise.then(value=>{
console.log(value)
},reason=>{
console.log(reason)
})
初步测试正常。
代码需求:添加一个异步任务,两秒后输出“成功拉”
const promise = new MyPromise((resolve,reject)=>{
setTimeout(()=>{
resolve("成功拉")
},2000)
//reject("失败")
})
当我们想要异步执行resolve,这时候我们的状态是等待的状态,我们上面的then方法中并没有判断等待的状态,所以我们上面的代码不会执行,这时我们应该判断一下状态,修改MyPromise.js文件
实现:
const PENDING = 'pending' //等待状态
const FULFILLED = 'fulfilled'//成功状态
const REJECTED = 'rejected'//失败状态
class MyPromise {
constructor(exector) {
//执行器
//创建peromise的时候传入的执行器会立刻执行
exector(this.resolve, this.reject)//传递进来两个函数,一个是成功的函数,一个失败的函数
}
status = PENDING;//设置默认的状态为等待状态
value = undefined //设置一开始传递进来的成功的值为undefined
reason = undefined //设置一开始传递进来的失败的值为undefined
+ fulfilledCallBack = undefined //把成功回调提升到全局
+ rejectedCallBack = undefined//把失败回调提升到全局
resolve = (value) => {
//value为传递进来的成功的值
//用来改变状态,把状态变为成功
if(this.status !== PENDING) return //因为状态是不可逆的,所以我们要在这里判断一下,以防更改状态
this.status = FULFILLED
this.value = value // 把传递进来的成功的值赋值
+ this.fulfilledCallBack && this.fulfilledCallBack(this.value) //如果成功回调存在就执行成功回调并把成功的值传递给它
}
reject = (reason) => {
//reason为传递进来的失败的原因
//用来改变状态,把状态变为失败
if(this.status !== PENDING) return //因为状态是不可逆的,所以我们要在这里判断一下,以防更改状态
this.status = REJECTED
this.reason = reason// 把传递进来的失败的原因赋值
+ this.rejectedCallBack && this.rejectedCallBack(this.reason) //如果失败回调存在就执行失败回调并把失败的原因传递给它
}
then = (fulfilledCallBack,rejectedCallBack)=>{
//then方法中有两个回调函数一个成功的fulfilledCallBack,一个失败的rejectedCallBack
if(this.status === FULFILLED) {
fulfilledCallBack(this.value)//将成功的值传给成功的回调函数
}else if(this.status === REJECTED){
rejectedCallBack(this.reason)//将失败的值传给失败的回调函数
+ }else{
+ //状态为等待状态,这是我们应该把成功的回调函数和失败的回调函数存储起来
+ this.fulfilledCallBack = fulfilledCallBack
+ this.rejectedCallBack = rejectedCallBack
}
}
}
module.exports = MyPromise
执行testPromise.js代码,我们的resolve是在两秒之后成功输出的
需求:多次调用then方法,依次输出三个“成功拉”
const promise = new MyPromise((resolve,reject)=>{
setTimeout(()=>{
resolve("成功拉")
},2000)
//reject("失败")
})
promise.then(value=>{
console.log(value)
},reason=>{
console.log(reason)
})
promise.then(value=>{
console.log(value)
},reason=>{
console.log(reason)
})
promise.then(value=>{
console.log(value)
},reason=>{
console.log(reason)
})
上面中我们的代码只会在两秒种以后输出一次“成功拉”,因为我们在上面的源码resolve和reject函数中,只是判断了成功回调和失败回调是否存在并且只执行了一次,我们现在要修改的就是将每一次的异步函数存储在一个数组当中,在resolve和reject中循环遍历执行他们
实现:
const PENDING = 'pending' //等待状态
const FULFILLED = 'fulfilled'//成功状态
const REJECTED = 'rejected'//失败状态
class MyPromise {
constructor(exector) {
//执行器
//创建peromise的时候传入的执行器会立刻执行
exector(this.resolve, this.reject)//传递进来两个函数,一个是成功的函数,一个失败的函数
}
status = PENDING;//设置默认的状态为等待状态
value = undefined //设置一开始传递进来的成功的值为undefined
reason = undefined //设置一开始传递进来的失败的值为undefined
_ //fulfilledCallBack = undefined //把成功回调提升到全局
_ //rejectedCallBack = undefined//把失败回调提升到全局
+ fulfilledCallBack = [] //把成功回调修改为数组存储每一个成功的回调
+ rejectedCallBack = []//把失败回调修改为数组存储每一个失败的回调
resolve = (value) => {
//value为传递进来的成功的值
//用来改变状态,把状态变为成功
if(this.status !== PENDING) return //因为状态是不可逆的,所以我们要在这里判断一下,以防更改状态
this.status = FULFILLED
this.value = value // 把传递进来的成功的值赋值
_ //this.fulfilledCallBack && this.fulfilledCallBack(this.value) //如果成功回调存在就执行成功回调并把成功的值传递给它
+ while(this.fulfilledCallBack.length) this.fulfilledCallBack.shift()(this.value)
}
reject = (reason) => {
//reason为传递进来的失败的原因
//用来改变状态,把状态变为失败
if(this.status !== PENDING) return //因为状态是不可逆的,所以我们要在这里判断一下,以防更改状态
this.status = REJECTED
this.reason = reason// 把传递进来的失败的原因赋值
_ //this.rejectedCallBack && this.rejectedCallBack(this.reason) //如果失败回调存在就执行失败回调并把失败的原因传递给它
+ while(this.rejectedCallBack.length) this.rejectedCallBack.shift()(this.reason)
}
then = (fulfilledCallBack,rejectedCallBack)=>{
//then方法中有两个回调函数一个成功的fulfilledCallBack,一个失败的rejectedCallBack
if(this.status === FULFILLED) {
fulfilledCallBack(this.value)//将成功的值传给成功的回调函数
}else if(this.status === REJECTED){
rejectedCallBack(this.reason)//将失败的值传给失败的回调函数
}else{
//状态为等待状态,这是我们应该把成功的回调函数和失败的回调函数存储起来
_ // this.fulfilledCallBack = fulfilledCallBack
_ // this.rejectedCallBack = rejectedCallBack
+ this.fulfilledCallBack.push(fulfilledCallBack) //将每一次成功的异步回调存储起来
+ this.rejectedCallBack.push(rejectedCallBack)//将每一次失败的异步回调存储起来
}
}
}
module.exports = MyPromise
需求:成功打印出"成功拉"和“100”
const MyPromise = require('./myPromise')
const promise = new MyPromise((resolve,reject)=>{
setTimeout(()=>{
resolve("成功拉")
},2000)
//reject("失败")
})
promise.then(value=>{
console.log(value)//成功拉
return '100'
})
.then(value=>{
console.log(value)//100
})
实现:如果我们想要链式调用then方法,只有promise对象才可以调用then方法,所以我们在then方法中应该需要返回一个promise对象。
//修改then方法:
then = (fulfilledCallBack, rejectedCallBack) => {//then方法中有两个回调函数一个成功的fulfilledCallBack,一个失败的rejectedCallBack
+ const promise = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
+ let x = fulfilledCallBack(this.value)//将成功的值传给成功的回调函数
+ resolve(x)
} else if (this.status === REJECTED) {
rejectedCallBack(this.reason)//将失败的值传给失败的回调函数
} else {
//状态为等待状态,这是我们应该把成功的回调函数和失败的回调函数存储起来
// this.fulfilledCallBack = fulfilledCallBack
// this.rejectedCallBack = rejectedCallBack
this.fulfilledCallBack.push(fulfilledCallBack) //将每一次成功的异步回调存储起来
this.rejectedCallBack.push(rejectedCallBack)//将每一次失败的异步回调存储起来
}
+ })
+ return promise
}
当我们在链式调用then方法中返回的是一个promise对象的时候,我们应该做以下处理实现我们正确的输出
需求:成功输出“成功啦”和“promise”
const MyPromise = require('./myPromise')
const promise = new MyPromise((resolve,reject)=>{
resolve("成功拉")
})
const test = () =>{
return new MyPromise((resolve,reject)=>{
setTimeout(()=>{
resolve("promise")
},2000)
})
}
promise.then(value=>{
console.log(value)
return test()
})
.then(value=>{
console.log(value)
})
实现:
then = (fulfilledCallBack, rejectedCallBack) => {
//then方法中有两个回调函数一个成功的fulfilledCallBack,一个失败的rejectedCallBack
const promise = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
let x = fulfilledCallBack(this.value)//将成功的值传给成功的回调函数
_ //resolve(x)
+ //1.判断x的值是普通对象还是promise对象
+ //2.如果是普通值我们直接调用resolve,并把x值传递进去
+ //3.如果是是promise对象,查看promise对象返回的结果
+ //4.再根据peomise对象返回的结果,决定调用resolve还是reject
+ //我们把上述判断封装成一个函数
+ resolvePromise(x,resolve,reject)
} else if (this.status === REJECTED) {
rejectedCallBack(this.reason)//将失败的值传给失败的回调函数
} else {
//状态为等待状态,这是我们应该把成功的回调函数和失败的回调函数存储起来
// this.fulfilledCallBack = fulfilledCallBack
// this.rejectedCallBack = rejectedCallBack
this.fulfilledCallBack.push(fulfilledCallBack) //将每一次成功的异步回调存储起来
this.rejectedCallBack.push(rejectedCallBack)//将每一次失败的异步回调存储起来
}
})
return promise
}
+function resolvePromise(x,resolve,reject){
+ if(x instanceof MyPromise){
+ //是promise
+ x.then(value=>{
resolve(value)},(reason)=>{
reject(reason)})
+ }else{
+ //普通值
+ resolve(x)
+ }
+}
在这里捕获两个地方的错误
1.立即执行器中的错误
2.then方法执行时的错误
constructor(exector) {
//执行器
try{
//创建peromise的时候传入的执行器会立刻执行
exector(this.resolve, this.reject)//传递进来两个函数,一个是成功的函数,一个失败的函数
}catch(err){
this.reject(err)
}
}
then = (fulfilledCallBack, rejectedCallBack) => {
//then方法中有两个回调函数一个成功的fulfilledCallBack,一个失败的rejectedCallBack
const promise = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
try{
let x = fulfilledCallBack(this.value)//将成功的值传给成功的回调函数
//resolve(x)
//1.判断x的值是普通对象还是promise对象
//2.如果是普通值我们直接调用resolve,并把x值传递进去
//3.如果是是promise对象,查看promise对象返回的结果
//4.再根据peomise对象返回的结果,决定调用resolve还是reject
//我们把上述判断封装成一个函数
resolvePromise(x,resolve,reject)
}catch(err){
reject(err)
}
} else if (this.status === REJECTED) {
rejectedCallBack(this.reason)//将失败的值传给失败的回调函数
} else {
//状态为等待状态,这是我们应该把成功的回调函数和失败的回调函数存储起来
// this.fulfilledCallBack = fulfilledCallBack
// this.rejectedCallBack = rejectedCallBack
this.fulfilledCallBack.push(fulfilledCallBack) //将每一次成功的异步回调存储起来
this.rejectedCallBack.push(rejectedCallBack)//将每一次失败的异步回调存储起来
}
})
return promise
}
处理异步resolve()
resolve = (value) => {
//value为传递进来的成功的值
//用来改变状态,把状态变为成功
if (this.status !== PENDING) return //因为状态是不可逆的,所以我们要在这里判断一下,以防更改状态
this.status = FULFILLED
this.value = value // 把传递进来的成功的值赋值
//this.fulfilledCallBack && this.fulfilledCallBack(this.value) //如果成功回调存在就执行成功回调并把成功的值传递给它
while (this.fulfilledCallBack.length) this.fulfilledCallBack.shift()()
}
reject = (reason) => {
//reason为传递进来的失败的原因
//用来改变状态,把状态变为失败
if (this.status !== PENDING) return //因为状态是不可逆的,所以我们要在这里判断一下,以防更改状态
this.status = REJECTED
this.reason = reason// 把传递进来的失败的原因赋值
//this.rejectedCallBack && this.rejectedCallBack(this.reason) //如果失败回调存在就执行失败回调并把失败的原因传递给它
while (this.rejectedCallBack.length) this.rejectedCallBack.shift()()
}
then = (fulfilledCallBack, rejectedCallBack) => {
//then方法中有两个回调函数一个成功的fulfilledCallBack,一个失败的rejectedCallBack
const promise = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(()=>{
try{
let x = fulfilledCallBack(this.value)//将成功的值传给成功的回调函数
//resolve(x)
//1.判断x的值是普通对象还是promise对象
//2.如果是普通值我们直接调用resolve,并把x值传递进去
//3.如果是是promise对象,查看promise对象返回的结果
//4.再根据peomise对象返回的结果,决定调用resolve还是reject
//我们把上述判断封装成一个函数
resolvePromise(promise,x,resolve,reject)
}catch(err){
reject(err)
}
},0)
} else if (this.status === REJECTED) {
setTimeout(()=>{
try{
let x = rejectedCallBack(this.reason)//将失败的值传给失败的回调函数
resolvePromise(promise,x,resolve,reject)
}catch(err){
reject(err)
}
},0)
} else {
//状态为等待状态,这是我们应该把成功的回调函数和失败的回调函数存储起来
// this.fulfilledCallBack = fulfilledCallBack
// this.rejectedCallBack = rejectedCallBack
this.fulfilledCallBack.push(()=>{
setTimeout(()=>{
try{
let x = fulfilledCallBack(this.value)//将失败的值传给失败的回调函数
resolvePromise(promise,x,resolve,reject)
}catch(err){
reject(err)
}
},0)
}) //将每一次成功的异步回调存储起来
this.rejectedCallBack.push(()=>{
setTimeout(()=>{
try{
let x = rejectedCallBack(this.reason)//将失败的值传给失败的回调函数
resolvePromise(promise,x,resolve,reject)
}catch(err){
reject(err)
}
},0)
})//将每一次失败的异步回调存储起来
}
})
return promise
}
思路:在 MyPromise类中定义一个静态方法all,Promise.all()中传入的是一个数组,遍历数组判断传递进来的数组是promise对象还是普通的值,如果是普通值则直接存到result数组中返回,如果是一个promise对象,则调用promise对象的then方法返回。
static all = (array) => {
let result = [] //存放最后 返回的值
let index = 0;//用来记录array中的值是否执行完
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value
index++;
if (index === array.length) {
//代表array执行完毕,直接返回result
resolve(result)
}
}
for (let i = 0; i < array.length; i++) {
if (array[i] instanceof MyPromise) {
//如果是promise对象
array[i].then(value => {
addData(i, value) }, reason => {
reject(reason) })
} else {
//普通值
addData(i, array[i])
}
}
})
}
思路:Promise.resolve()方法中如果传递的是一个promise对象,则直接返回原路返回,如果是一个普通值得话,则封装成promise对象将值返回,这样resolve才可以使用then
static resolve = (value) => {
if (value instanceof MyPromise) return value
return new MyPromise((resolve, reject) => resolve(value))
}
思路:在MyPromise中定义一个内部方法catch(),catch中传入得是失败得回调函数,我们直接返回then方法中得失败回调即可
catch = (rejectedCallBack) => {
return this.then(undefined, rejectedCallBack)
}
const PENDING = 'pending' //等待状态
const FULFILLED = 'fulfilled'//成功状态
const REJECTED = 'rejected'//失败状态
class MyPromise {
constructor(exector) {
//执行器
try {
//创建peromise的时候传入的执行器会立刻执行
exector(this.resolve, this.reject)//传递进来两个函数,一个是成功的函数,一个失败的函数
} catch (err) {
this.reject(err)
}
}
status = PENDING;//设置默认的状态为等待状态
value = undefined //设置一开始传递进来的成功的值为undefined
reason = undefined //设置一开始传递进来的失败的值为undefined
//fulfilledCallBack = undefined //把成功回调提升到全局
//rejectedCallBack = undefined//把失败回调提升到全局
fulfilledCallBack = [] //把成功回调修改为数组存储每一个成功的回调
rejectedCallBack = []//把失败回调修改为数组存储每一个失败的回调
resolve = (value) => {
//value为传递进来的成功的值
//用来改变状态,把状态变为成功
if (this.status !== PENDING) return //因为状态是不可逆的,所以我们要在这里判断一下,以防更改状态
this.status = FULFILLED
this.value = value // 把传递进来的成功的值赋值
//this.fulfilledCallBack && this.fulfilledCallBack(this.value) //如果成功回调存在就执行成功回调并把成功的值传递给它
while (this.fulfilledCallBack.length) this.fulfilledCallBack.shift()()
}
reject = (reason) => {
//reason为传递进来的失败的原因
//用来改变状态,把状态变为失败
if (this.status !== PENDING) return //因为状态是不可逆的,所以我们要在这里判断一下,以防更改状态
this.status = REJECTED
this.reason = reason// 把传递进来的失败的原因赋值
//this.rejectedCallBack && this.rejectedCallBack(this.reason) //如果失败回调存在就执行失败回调并把失败的原因传递给它
while (this.rejectedCallBack.length) this.rejectedCallBack.shift()()
}
then = (fulfilledCallBack, rejectedCallBack) => {
//then方法中有两个回调函数一个成功的fulfilledCallBack,一个失败的rejectedCallBack
fulfilledCallBack = fulfilledCallBack ? fulfilledCallBack : value => value //判断then方法中是否传递了成功函数,如果没有传递则默认把value向下传递
rejectedCallBack = rejectedCallBack ? rejectedCallBack : reason => {
throw reason }
const promise = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
let x = fulfilledCallBack(this.value)//将成功的值传给成功的回调函数
//resolve(x)
//1.判断x的值是普通对象还是promise对象
//2.如果是普通值我们直接调用resolve,并把x值传递进去
//3.如果是是promise对象,查看promise对象返回的结果
//4.再根据peomise对象返回的结果,决定调用resolve还是reject
//我们把上述判断封装成一个函数
resolvePromise(promise, x, resolve, reject)
} catch (err) {
reject(err)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = rejectedCallBack(this.reason)//将失败的值传给失败的回调函数
resolvePromise(promise, x, resolve, reject)
} catch (err) {
reject(err)
}
}, 0)
} else {
//状态为等待状态,这是我们应该把成功的回调函数和失败的回调函数存储起来
// this.fulfilledCallBack = fulfilledCallBack
// this.rejectedCallBack = rejectedCallBack
this.fulfilledCallBack.push(() => {
setTimeout(() => {
try {
let x = fulfilledCallBack(this.value)//将失败的值传给失败的回调函数
resolvePromise(promise, x, resolve, reject)
} catch (err) {
reject(err)
}
}, 0)
}) //将每一次成功的异步回调存储起来
this.rejectedCallBack.push(() => {
setTimeout(() => {
try {
let x = rejectedCallBack(this.reason)//将失败的值传给失败的回调函数
resolvePromise(promise, x, resolve, reject)
} catch (err) {
reject(err)
}
}, 0)
})//将每一次失败的异步回调存储起来
}
})
return promise
}
catch = (rejectedCallBack) => {
return this.then(undefined, rejectedCallBack)
}
static all = (array) => {
let result = [] //存放最后 返回的值
let index = 0;//用来记录array中的值是否执行完
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value
index++;
if (index === array.length) {
//代表array执行完毕,直接返回result
resolve(result)
}
}
for (let i = 0; i < array.length; i++) {
if (array[i] instanceof MyPromise) {
//如果是promise对象
array[i].then(value => {
addData(i, value) }, reason => {
reject(reason) })
} else {
//普通值
addData(i, array[i])
}
}
})
}
static resolve = (value) => {
if (value instanceof MyPromise) return value
return new MyPromise((resolve, reject) => resolve(value))
}
}
function resolvePromise(promise, x, resolve, reject) {
if (promise === x) {
return new Error("detelete promise")
}
if (x instanceof MyPromise) {
//是promise
x.then(value => {
resolve(value) }, (reason) => {
reject(reason) })
} else {
//普通值
resolve(x)
}
}
module.exports = MyPromise