一、初始化版本
- 1.Promise 就是一个类 在执行这个类的时候 需要传递一个(回调函数)执行器进去 执行器立即执行
- 2.Promise有三种状态 fulfilled rejected pending
- 3.pending -> fulfilled rejected
- resolve和reject就是用来更改状态的
- 状态一旦确定则不可更改
- 4.then方法内部做的事情就是判断状态,如果状态成功则执行成功的回调 失败则执行失败的回调 是被定义在原型对象中的
- 5.then成功之后有一个参数,表示成功后的值,失败后有一个失败原因
// Promise有三种状态 fulfilled rejected pending
const FULFILLED = 'fulfulled'
const REJECT = 'reject'
const PENDING = 'pending'
// Promise 就是一个类
class myPromise{
// 在执行这个类的时候 需要传递一个(回调函数)执行器进去
constructor(executor) {
// 执行器立即执行
executor(this.resolve, this.reject)
}
status = PENDING
successCallback = undefined
failCallback = undefined
value = undefined
reason = undefined
resolve = (value => {
// 状态一旦确定则不可更改
if(this.status !== PENDING) return
// resolve和reject就是用来更改状态的
this.status = FULFILLED
this.value = value
})
reject = (reason => {
// 状态一旦确定则不可更改
if(this.status !== PENDING) return
// resolve和reject就是用来更改状态的
this.status = REJECT
this.reason = reason
})
then = ((sucessCallback, failCallback) => {
// then方法内部做的事情就是判断状态,被定义在原型对象中的
if(this.status === FULFILLED) {
// 状态成功则执行成功的回调,传入成功后的值
sucessCallback(this.value)
} else if (this.status === REJECT) {
// 状态失败则执行失败的回调,传入失败后的原因
failCallback(this.reason)
} else {
// 等待 将成功回调和失败回调存储起来
this.successCallback = sucessCallback
this.failCallback = failCallback
}
})
}
// 测试
new Promise((resolve, reject) => {
// resolve(7)
reject('cuole')
}).then((value)=>{
console.log(value)
},reason=>{
console.log(reason)
})
二:then方法
1.多次调用添加多个处理函数
- 分同步的情况和异步的情况,同步的情况不需要处理
- 异步的情况下每一个回调函数的状态都应该存储起来 需要保证前一个函数结束后执行另一个函数 等到状态编程成功或者失败的时候再依次调用
2.链式调用
- then方法的链式调用:每个then方法返回一个promise对象
- 后面then方法的回调函数拿到值是上一个then方法的回调函数的返回值
- 判断返回值x是普通值还是promise对象
普通值: 直接调用resolve
promise对象: 查看promise对象返回的结果 根据promise对象返回的结果,决定调用resolve还是reject
3.识别Promise对象自返回
- 在then方法的回调函数中,不能返回当前then方法返回的promise对象 否则会造成promise的循环调用 会报错
- 需要判断回调函数跟当前的promise是不是相等 如果相等直接reject
4.then方法的参数变成可选参数
- 如果then方法没有传递参数,那么就补充一个函数进来
5.捕获错误以及then链式调用其他状态代码补充
- try-catch捕获当前Promise对象
- 捕获then链式调用中的回调函数的错误
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
constructor (executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e);
}
}
// promsie 状态
status = PENDING;
// 成功之后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
resolve = value => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 判断成功回调是否存在 如果存在 调用
// this.successCallback && this.successCallback(this.value);
while(this.successCallback.length) this.successCallback.shift()()
}
reject = reason => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason;
// 判断失败回调是否存在 如果存在 调用
// this.failCallback && this.failCallback(this.reason);
while(this.failCallback.length) this.failCallback.shift()()
}
then (successCallback, failCallback) {
// 参数可选
successCallback = successCallback ? successCallback : value => value;
// 参数可选
failCallback = failCallback ? failCallback: reason => { throw reason };
let promsie2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promsie2, x, resolve, reject)
}catch (e) {
reject(e);
}
}, 0)
}else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promsie2, x, resolve, reject)
}catch (e) {
reject(e);
}
}, 0)
} else {
// 等待
// 将成功回调和失败回调存储起来
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promsie2, x, resolve, reject)
}catch (e) {
reject(e);
}
}, 0)
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promsie2, x, resolve, reject)
}catch (e) {
reject(e);
}
}, 0)
});
}
});
return promsie2;
}
}
function resolvePromise (promsie2, x, resolve, reject) {
if (promsie2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason));
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
三、最终版本
1.Promise.all方法的实现
解决异步并发问题 以调用的顺序获取结果
- 静态方法,接受数组作为参数
- 返回的是一个Promise对象
- 循环数组判断数组当前值是普通值 or Promise对象,普通值直接输出 Promise对象需要先执行 执行后的返回的结果放到数组中 最后输出一个结果数组
- 注意异步操作情况,需要等待异步操作完成之后才能resolve 使用index记录返回数组的长度,如果index与数组长度不一致则等待一致后返回
2.Promise.resolve方法的实现
将给定值转换成promise对象 返回值是一个promise对象 返回的promise中包裹着给定值
- 接受的值判断当前值是普通值(用promise对象包裹) or Promise对象(原封不动返回)
3.finally方法的实现
1.无论promise对象成功或者失败 回调函数始终都会被执行
2.finally方法后面的then方法可以拿到当前promise对象返回的结果
实现:
- 需要定义在promise的原型链中 接受一个回调函数作为参数 使用this.then方法来获取当前promise对象状态 成功和失败回调函数中调用回调函数
- finally方法需要返回一个promise对象 需要在then方法中拿到成功的值或者失败结果 return 或者 throw的方式传递出去
- 注意:finally方法如果返回的是一个异步执行的函数 此时finally方法的then方法可能返回值还是上一个的结果 需要等待 此时需要借助promise的resolve方法:接受的值判断当前值是普通值(用promise对象包裹) or Promise对象(原封不动返回)
4..catch方法的实现
当前promise最终状态为失败的情况
- 在catch方法的内部去调用then方法 成功回调传入undefined 失败的传入回调函数
// Promise有三种状态 fulfilled rejected pending
const fulfilled = 'fulfilled'
const rejected = 'rejected'
const pending = 'pending'
class myPromise {
constructor (executor) {
// 执行器立即执行
// 捕获执行器错误
try {
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
}
// promise状态
status = pending
// 成功的值
_value = undefined
// 失败的原因
_reason = undefined
// 成功回调 多个 每个回调函数的状态都应该存储起来
sucessCallback = []
// 失败回调
failCallback = []
// 箭头函数是考虑this指向
resolve = (value)=> {
// 状态一旦确定则不可更改
if(this.status!==pending) return
// resolve和reject就是用来更改状态的
this.status = fulfilled
this._value = value
// 成功则执行成功的回调
// this.sucessCallback && this.sucessCallback(this._value)
while (this.sucessCallback.length) this.sucessCallback.shift()()
}
reject = (reason)=> {
if(this.status!==pending) return
this.status = rejected
this._reason = reason
// this.failCallback && this.failCallback(this._reason)
while (this.failCallback.length) this.failCallback.shift()()
}
// 判断状态,如果状态成功则执行成功的回调 失败则执行失败的回调
then = (sucessCallback, failCallback) => {
sucessCallback = sucessCallback ? sucessCallback : value => value
failCallback = failCallback ? failCallback : reason => {throw reason}
// then方法的回调函数拿到值是上一个then方法的回调函数的返回值
let promise2 = new myPromise((resolve, reject) => {
// 判断状态
if(this.status === fulfilled) {
setTimeout(() => {
try {
let x = sucessCallback(this._value)
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promise2, x, resolve, reject)
}catch (e) {
reject(e);
}
}, 0)
// // 为了把promise执行完成之后再执行里面的代码
// setTimeout(() => {
// // 成功之后有一个参数
// let x = sucessCallback(this._value)
// // resolve(x)
// // 判断返回值类型,并做相应处理
// resolvePromise(promise2, x, resolve, reject)
// }, 0);
} else if (this.status === rejected) {
setTimeout(() => {
try {
let x = failCallback(this._reason);
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promise2, x, resolve, reject)
}catch (e) {
reject(e);
}
}, 0)
} else {
// 异步逻辑 等待
// 将成功回调和失败回调存储起来
// this.sucessCallback.push(sucessCallback)
// this.failCallback.push(failCallback)
this.sucessCallback.push(() => {
setTimeout(() => {
try {
let x = sucessCallback(this._value);
resolvePromise(promise2, x, resolve, reject)
}catch (e) {
reject(e);
}
}, 0)
})
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this._reason)
resolvePromise(promise2, x, resolve, reject)
}catch (e) {
reject(e);
}
}, 0)
})
}
})
return promise2
}
static all (arr) {
let res = []
let index = 0
return new myPromise((resolve, reject)=>{
function addData(key, value) {
res[key] = value
index++
if(index === arr.length) resolve(res)
}
for(let i=0;i<arr.length;i++){
let current = arr[i]
if(current instanceof myPromise) {
// Promise对象
current.then(value=>{
addData(i, value)
},reason=>{reject(reason)})
} else {
// 普通值 直接push进去数组
addData(i, arr[i])
}
}
})
}
static resolve (val) {
if(val instanceof myPromise) return val
return new myPromise(resolve=>resolve(val))
}
finally (callback){
return this.then((val)=>{
return myPromise.resolve(callback()).then(()=> val)
// callback(val)
// return val
},reason=>{
return myPromise.resolve(callback()).then(()=> {throw reason})
// callback(reason)
// return reason
})
// return new myPromise(resolve=>resolve())
}
catch (callback) {
// 1.在catch方法的内部去调用then方法 成功回调传入undefined 失败的传入回调函数
// return this.then(undefined, callback)
return this.then(()=>{
return undefined
}, reason=>{
callback(reason)
})
}
}
function resolvePromise (promise2, x, resolve, reject) {
if(promise2 === x) {
return x.reject(new TypeError('循环调用了'))
}
if(x instanceof myPromise) {
// 根据promise对象返回的结果,决定调用resolve还是reject
// x.then(value => resolve(value), reason => reject(reason))
x.then(resolve, reject)
} else {
resolve(x)
}
}
原创文章,作者:一苇,如若转载,请注明出处:https://wsppx.cn/895/%e7%bd%91%e7%bb%9c%e5%bc%80%e5%8f%91/%e5%89%8d%e7%ab%af/