手写一个Promise(严格按照Promise/a+规范)
- 规范 Promise/A+
- Promise类的设计 Class HYpromise 3.构造函数的规划
class HYpromise{
construrctor(executor)
// 定义状态
// 定义resolve reject回调
// 使用resolve执行微任务队列 改变状态 获取value then传入执行成功回调
// reject 执行微任务队列 改变状态 获取reason then传入失败回调
//try catch 检测异常
excutor(resolve,reject)
}
}
4.then方法的实现
class HYpromise{
then(onFulfilled,onReject){
this.onFulfilled=onFulfilled
this.onReject=onReject
1.判断onFulfilled,onReject 会给默认值
2.返回Promise resolve/reject
3.判断之前的promise状态是否确定
onFulfilled,onReject直接执行(捕获异常)
4.添加到数组push(()=>{执行onFulfilled/onReject 直接执行代码})
}
}
5.catch方法
// 直接实现catch 给他一个返回值 因为调then 都会执行传入的函数
return this.then(undefined, onRehected);
}
6.finally
class HYpromise{
// 不会成功还是失败 他都会调用onFinally函数
this.then(
() => {
onFinally();
},
() => {
onFinally();
}
);
}
7.resolve/reject
static resolve(value) {
return new HYPromise(resolve => resolve(value));
}
static reject(reason) {
return new HYPromise(reject => reject(reason));
}
实现代码
// 手写Promise
// 需要按照Promise/A+
// Promise目前的状态 状态管理
const PROMISE_STATUS_PENDING = 'pending';
const PROMISE_STATUS_FULFILLED = 'fulfiled';
const PROMISE_STATUS_REJECT = 'reject';
// 工具函数 封装函数
function execFunctionWithCatchErrorFun(exeFn, value, resolve, reject) {
try {
const result = exeFn(value);
resolve(result);
} catch (error) {
reject(error);
}
}
class HYPromise {
constructor(executor) {
// 刚开始调用 是pending 初始值
this.status = PROMISE_STATUS_PENDING;
this.value = undefined;
this.reason = undefined;
// 2.所有的回调保存在一个数组里面 这样可以多次调用同一个promise
this.onFulfilledFns = [];
this.onRehectedFms = [];
const resolve = value => {
if (this.status === PROMISE_STATUS_PENDING) {
// 1.利用event Loop的宏任务 微任务来 为了不堵塞主线程任务
// setTimeout 是一个宏任务
// 修改状态的需要在本轮的事件任务改
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return;
this.status = PROMISE_STATUS_FULFILLED;
// then接受的参数
this.value = value;
console.log('resolve被调用', value);
// then传进来的回调函数
// this.onFulfilled(this.value);
// 2.执行加入数组的回调函数
this.onFulfilledFns.forEach(fn => {
fn(this.value);
});
}, 0);
}
};
const reject = reason => {
if (this.status === PROMISE_STATUS_PENDING) {
// 2.因为promise本身就是一个微任务 所以不要给他加入宏任务,使用queueMicrotask把函数加入微任务里面 他也会延迟调用 他会在本轮的事件循环后调用
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return;
this.reason = reason;
this.status = PROMISE_STATUS_REJECT;
console.log('reject被调用', reason);
// this.onRehected(this.reason);
// 2.执行加入数组的回调函数
this.onRehectedFms.forEach(fn => {
fn(this.reason);
});
});
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRehected) {
// 3. 当封装catch 时候会直接调用then方法 他就没有onRehected参数 这个时候直接抛出异常 这样会直接走本身的reject的catch方法
// onRehected =
// onRehected === undefined
// ? err => {
// throw err;
// }
// : onRehected;
onRehected =
onRehected ||
(err => {
throw err;
});
onFulfilled =
onFulfilled ||
(value => {
return value;
});
// 为了返回一个Promise 实现链式调用
return new HYPromise((resolve, reject) => {
// this.onFulfilled = onFulfilled;
// this.onRehected = onRehected;
// 2.如果当前已经有了状态 直接执行本次函数
// 为了有延迟执行的then回调函数 更加严谨
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
// 因为链式调用 返回的都是resolve 也就是then的回调函数 只有当异常了 才会调reject
// try {
// const value = onFulfilled(this.value);
// resolve(value);
// } catch (error) {
// reject(error);
// }
// 3.使用封装函数
execFunctionWithCatchErrorFun(onFulfilled, this.value, resolve, reject);
}
if (this.status === PROMISE_STATUS_REJECT && onRehected) {
// 因为链式调用 返回的都是resolve 也就是then的回调函数 只有当异常了 才会调reject
// try {
// const reason = onRehected(this.reason);
// resolve(reason);
// } catch (error) {
// reject(error);
// }
// 3.使用封装函数
execFunctionWithCatchErrorFun(onRehected, this.reason, resolve, reject);
}
// 2.then 多次调用 把所有的回调加入一个数组里面 如果当前状态时padding的话 加入数组
if (this.status === PROMISE_STATUS_PENDING) {
if (onFulfilled)
this.onFulfilledFns.push(() => {
// 返回一个函数 当函数执行的时候可以拿到函数值
// try {
// const value = onFulfilled(this.value);
// resolve(value);
// } catch (error) {
// reject(error);
// }
// 3.使用封装函数
execFunctionWithCatchErrorFun(
onFulfilled,
this.value,
resolve,
reject
);
});
if (onRehected)
this.onRehectedFms.push(() => {
// try {
// const reason = onRehected(this.reason);
// resolve(reason);
// } catch (error) {
// reject(error);
// }
// 3.使用封装函数
execFunctionWithCatchErrorFun(
onRehected,
this.reason,
resolve,
reject
);
});
}
});
}
catch(onRehected) {
// 直接实现catch 给他一个返回值 因为调then 都会执行传入的函数
return this.then(undefined, onRehected);
}
finally(onFinally) {
// 不会成功还是失败 他都会调用onFinally函数
this.then(
() => {
onFinally();
},
() => {
onFinally();
}
);
}
static resolve(value) {
return new HYPromise(resolve => resolve(value));
}
static reject(reason) {
return new HYPromise(reject => reject(reason));
}
static all(promises) {
return HYPromise((resolve, reject) => {
const values = [];
promises.forEach(promises => {
promises.then(
res => {
values.push(res);
if (values.length === promises.length) {
resolve(values);
}
},
err => {
reject(err);
}
);
});
});
}
static allSettled(promises) {
return HYPromise(resolve => {
const values = [];
promises.forEach(promises => {
promises.then(
res => {
values.push({ status: PROMISE_STATUS_FULFILLED, value: res });
if (values.length === promises.length) {
resolve(values);
}
},
err => {
values.push({ status: PROMISE_STATUS_REJECT, value: err });
if (values.length === promises.length) {
resolve(values);
}
}
);
});
});
}
static race(promises) {
return HYPromise(resolve => {
promises.forEach(promise => {
// promises.then(
// res => {
// resolve(res);
// },
// err => {
// reject(err);
// }
// );
// 简写
promise.then(resolve, reject);
});
});
}
static any(promises) {
// 至少有一个成功的 resolve
// 所有的都失败了 reject
const reasons = [];
return HYPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(resolve, err => {
reasons.push(err);
if (reasons.length === promises.length) {
// 捕获异常是一个数组
reject(new AggregateError(reasons));
}
});
});
});
}
}
const promise = new HYPromise((resolve, reject) => {
resolve(1111);
reject(2222);
});
promise.then(
res => {
console.log(res);
},
err => {
console.log(err);
}
);