promise
javascript
const PENDING = "pending";
const RESOLVED = "resolved";
const REJECTED = "rejected";
function MyPromise(fn) {
// 保存初始化状态
var self = this;
// 初始化状态
this.state = PENDING;
// 用于保存 resolve 或者 rejected 传入的值
this.value = null;
// 用于保存 resolve 的回调函数
this.resolvedCallbacks = [];
// 用于保存 reject 的回调函数
this.rejectedCallbacks = [];
// 状态转变为 resolved 方法
function resolve(value) {
// 判断传入元素是否为 Promise 值,如果是,则状态改变必须等待前一个状态改变后再进行改变
if (value instanceof MyPromise) {
return value.then(resolve, reject);
}
// 保证代码的执行顺序为本轮事件循环的末尾(可降级用setTimeout)
queueMicrotask(() => {
// 只有状态为 pending 时才能转变,
if (self.state === PENDING) {
// 修改状态
self.state = RESOLVED;
// 设置传入的值
self.value = value;
// 执行回调函数
self.resolvedCallbacks.forEach(callback => {
callback(value);
});
self.resolvedCallbacks=[]
}
});
}
// 状态转变为 rejected 方法
function reject(value) {
// 判断传入元素是否为 Promise 值,如果是,则状态改变必须等待前一个状态改变后再进行改变
if (value instanceof MyPromise) {
return value.then(resolve, reject);//手动拆包
}
// 保证代码的执行顺序为本轮事件循环的末尾
queueMicrotask(() => {
// 只有状态为 pending 时才能转变
if (self.state === PENDING) {
// 修改状态
self.state = REJECTED;
// 设置传入的值
self.value = value;
// 执行回调函数
self.rejectedCallbacks.forEach(callback => {
callback(value);
});
self.rejectedCallbacks=[]
}
});
}
// 将两个方法传入函数执行
try {
fn(resolve, reject);
} catch (e) {
// 遇到错误时,捕获错误,执行 reject 函数
reject(e);
}
}
MyPromise.prototype.then = function (onFulfilled, onReject) {
// 可选参数兜底,不传时提供默认回调
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : val => val;
onReject = typeof onReject === "function" ? onReject : err => { throw err };
const self = this;
// then 必须返回新 Promise 实现链式
return new MyPromise((resolve, reject) => {
// 成功封装函数(前一个promise成功时执行的函数)
let fulfilled = () => {
try {
const result = onFulfilled(self.value);
// 如果回调返回Promise,等待它完成再改变新promise状态
result instanceof MyPromise ? result.then(resolve, reject) : resolve(result);
} catch (err) {
reject(err);
}
};
// 失败封装函数(前一个promise失败时执行的函数)
let rejected = () => {
try {
const result = onReject(self.value);
result instanceof MyPromise ? result.then(resolve, reject) : resolve(result);
} catch (err) {
reject(err);
}
};
switch (self.state) {
case PENDING:
self.resolvedCallbacks.push(fulfilled);
self.rejectedCallbacks.push(rejected);
break;
case RESOLVED:
fulfilled();
break;
case REJECTED:
rejected();
break;
}
})
};
promise.all
javascript
function promiseAll(promises) {
// 返回一个全新的Promise实例
return new Promise(function(resolve, reject) {
// 判断传入参数是否为数组,非数组直接抛出类型错误
if (!Array.isArray(promises)) {
throw new TypeError(`argument must be a array`)
}
// 记录已成功完成的Promise数量
let resolvedCounter = 0;
// 保存传入数组总长度
let promiseNum = promises.length;
// 存储所有Promise成功后的结果,下标与入参数组保持一致
let resolvedResult = [];
// 处理空数组特殊情况
if (promiseNum === 0) {
return resolve([])
}
// 循环遍历所有传入的任务
for (let i = 0; i < promiseNum; i++) {
// 使用Promise.resolve包装,兼容数组中传入普通值的情况
Promise.resolve(promises[i])
.then(value => {
// 当前任务成功,成功计数+1
resolvedCounter++;
// 将结果存入对应下标,保证输出数组顺序和输入一致
resolvedResult[i] = value;
// 所有任务全部执行成功
if (resolvedCounter == promiseNum) {
// 把完整结果数组resolve出去
resolve(resolvedResult)
}
}, error => {
// 任意一个任务失败,直接reject失败原因,终止后续处理
reject(error)
})
}
})
}
promise.race
javascript
Promise.race = function (args) {
// 参数校验
if (!Array.isArray(args)) {
throw new TypeError('args must be an array')
}
return new Promise((resolve, reject) => {
for (let i = 0, len = args.length; i < len; i++) {
// 使用Promise.resolve包装,兼容普通值
Promise.resolve(args[i]).then(resolve, reject)
}
})
}
promise.allSettled
javascript
Promise.allSettled = function (promises) {
// 参数校验
if (!Array.isArray(promises)) {
throw new TypeError('promises must be an array')
}
return new Promise((resolve) => {
let count = 0
const result = []
const len = promises.length
// 边界:空数组直接返回
if (len === 0) {
return resolve([])
}
for (let i = 0; i < len; i++) {
// Promise.resolve 兼容普通非Promise值
Promise.resolve(promises[i])
.then((value) => {
result[i] = {
status: 'fulfilled',
value
}
})
.catch((reason) => {
result[i] = {
status: 'rejected',
reason
}
})
.finally(() => {
count++
// 全部处理完成
if (count === len) {
resolve(result)
}
})
}
})
}