class Promise1 {
// promise/A+ 规范:promise状态返回fulfilled(成功),返回的是一个不可以改变的value
// promise/A+ 规范:promise状态返回rejected(失败),返回的是一个不可以改变的reason
// promise/A+ 规范:判断状态是否为pending 是pending才可以进行状态改变
// 2.此时传入一个匿名函数 这时候executor就是这个匿名函数 我们去看 try catch部分 ↓
constructor(executor) {
// 初始化的状态
this.state = 'pending'
// 成功的值
this.value = undefined
// 失败的值
this.reason = undefined
// 成功存放的数组
this.onResolvedCallbacks = [];
// 失败存放的数组
this.onRejectedCallbacks = [];
// 成功
let resolve = (value) => {
if (this.state == 'pending') {
this.state = 'fulfilled'
this.value = value
// 一旦resolve 执行, 调用成功数组的函数
this.onResolvedCallbacks.forEach(fn => fn());
}
}
// 失败
let reject = (reason) => {
if (this.state == 'pending') {
this.state = 'rejected'
this.reason = reason
// 一旦 resolve执行 , 调用失败数组的函数
this.onRejectedCallbacks.forEach(fn => fn());
}
}
// (resolve, reject) => {
// resolve('1') 相当于=========>
// })
// executor = (resolve, reject) => {
// resolve('1')
// })
// 执行 如果executor执行出错,执行catch的reject失败
try {
// 执行这个函数 executor()
// 3.往这个匿名函数传入上面定义的成功和失败的resolve 和 reject的方法 作为参数 executor(resolve, reject)
executor(resolve, reject)
} catch{
reject(err)
}
}
// then方法
// onFulfilled,onRejected分别是一个函数
// 如果状态为fulfilled 执行 onFulfilled ,传入成功的value
// 如果失败,传入onRejected,传入失败的reason
// 链式调用, new Promise().then().then(),这就是链式调用
// 为了达成链式 , 我们默认在第一个then里返回一个Promise. 规定 : 在then里面返回一个新的Promise , 称为promise2;
// promise2 = new Promise((resolve,reject)=>{})
// 规定 : onFulfilled()或 onRejected()的值 , 即第一个then返回的值 , 叫做 x ,判断 x 的函数叫做 resolvePromise
then(onFulfilled, onRejected) {
// onFulfilled 如果不是函数 , 就忽略 onFulfilled , 直接返回 value
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;
// onRejected 如果不是函数 , 就忽略 onRejected , 直接扔出错误
onRejected = typeof onRejected === "function" ? onRejected : err => { throw err };
// 声明返回的 promise2
// 规定 : 一段代码 , 让不同的promise代码互相套用 , 叫做resolvePromise
let promise2 = new Promise1((resolve, reject) => {
// 状态为 fulfilled , 执行 onFulfiiled , 传入成功的值
if (this.state == 'fulfilled') {
// 规定 onFulfilled 或 onRejected 不能同步被调用,必须异步调用。我们就用 setTimeout解决异步问题
setTimeout(() => {
try {
let x = onFulfilled(this.value);
// resolvePromise函数 , 处理自己return 的promise和默认的promise2的关系
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0)
}
//状态为 rejected , 执行onRejected , 传入失败的原因
if (this.state === 'rejected') {
//异步
setTimeout(() => {
// 如果报错
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
};
// 当状态为 pending时
if (this.state === 'pending') {
// onFulfilled 传入到成功数组中
this.onResolvedCallbacks.push(() => {
//异步
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}
}, 0);
})
// onRejected 传入到失败数组
this.onRejectedCallbacks.push(() => {
// 异步
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}
}, 0)
})
}
})
// 返回promise2 , 完成链式
return promise2
}
catch(fn) {
return this.then(null, fn)
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (x === promise2) {
return reject(new TypeError("Chaining cycle detected for promise"));
}
// 防止多次调用
let called;
// x 不是 null 并且 x 是对象或者函数
if (x != null && (typeof x === 'object' || typeof x === 'function')) {
try {
// A+ 规定 , 声明 then = x 的then 方法
let then = x.then;
// 如果 then 是函数 , 就默认是 promise了
if (typeof then === 'function') {
// 就让 then 执行 第一个参数是 this 后面是成功的回调和 失败的回调
then.call(x, y => {
// 成功和失败只能调用一个
if (called) return;
called = true;
// resolve 的结果依旧是 promise 那就继续解析
resolvePromise(promise2, y, resolve, reject);
}, err => {
// 成功和失败只能调用一个
if (called) return;
called = true;
reject(err); // 失败了就失败了
})
} else {
resolve(x); //直接成功即可
}
} catch (e) {
// 也属于失败
if (called) return;
called = true;
// 取then出错了 那就不要再继续执行了
reject(e);
}
} else {
resolve(x);
}
}
// 1.promise里实例化的是一个匿名函数 往consturtor那里看 ↑
let b = new Promise1((resolve, reject) => {
// 4.拿出回调出来的方法
reject('error')
})
b.then(res => {
console.log('success');
},err => {
console.log(err);
})
// b.then(res => {
// console.log(res);
// return new Promise1((resolve, reject) => {
// resolve('成功回调')
// })
// })
// .then(res => {
// console.log(res);
// }).catch(err => {
// console.log(err);
// })
临场发挥--实现手写promise
最新推荐文章于 2023-12-19 16:24:11 发布