一、定义promise类
promise主要用于处理异步操作的方法,它可以用于避免回调地狱的问题,它在事件循环中属于异步任务中的微任务,.then后面的内容。
promise有三种状态,pending,fulfilled,rejected,可以由pending转化成其他的两个状态而不能返回原来的状态。当promise的构造器执行resolve的回调时候,pending的状态会变成fulfilled,当构造器执行rejected的回调时候,pending的状态会变成rejected
ini
// 定义 Promise 的三种状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
// 初始化状态为 pending
this.status = PENDING;
// 存储成功的值
this.value = undefined;
// 存储失败的原因
this.reason = undefined;
// 存储成功的回调函数
this.onFulfilledCallbacks = [];
// 存储失败的回调函数
this.onRejectedCallbacks = [];
// 成功的处理函数
const resolve = (value) => {
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
// 执行所有成功的回调函数
this.onFulfilledCallbacks.forEach(callback => callback());
}
};
// 失败的处理函数
const reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
// 执行所有失败的回调函数
this.onRejectedCallbacks.forEach(callback => callback());
}
};
二、then方法
.then方法,该方法是对回调函数进行处理,当状态是fulfilled的时候,会执行成功的回调,当状态是rejected的时候执行失败的回调,
- 需要判定onFulfilled是否是个函数,如果不是函数则直接返回相应的值,
- 后面判定的操作是加入异步的方式,只有加上settimeout的方式才能实现promise的异步操作。
- 一定要有pending值的状态判定,否则当宏任务中套微任务时候,就无法正确输出成功的回调,当状态是pending的时候,需要将成功或者失败的回调函数存储起来,
- 在执行then函数的时候需要定义一个新的promise函数,这是由于为了实现链式的调用,
javascript
then(onFulfilled, onRejected) {
// 处理 onFulfilled 不是函数的情况
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
// 处理 onRejected 不是函数的情况
onRejected = typeof onRejected === 'function' ? onRejected : error => { throw error; };
const newPromise = new MyPromise((resolve, reject) => {
const handleFulfilled = () => {
try {
const result = onFulfilled(this.value);
// 如果 result 是一个 Promise 实例
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
// 否则直接将结果传递给新 Promise 的 resolve 方法
resolve(result);
}
} catch (error) {
// 如果执行出错,调用新 Promise 的 reject 方法
reject(error);
}
};
const handleRejected = () => {
try {
const result = onRejected(this.reason);
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
};
if (this.status === FULFILLED) {
// 如果状态已经是 fulfilled,立即执行成功的回调函数
setTimeout(handleFulfilled, 0);
} else if (this.status === REJECTED) {
// 如果状态已经是 rejected,立即执行失败的回调函数
setTimeout(handleRejected, 0);
} else {
// 如果状态还是 pending,将回调函数存储起来
this.onFulfilledCallbacks.push(() => setTimeout(handleFulfilled, 0));
this.onRejectedCallbacks.push(() => setTimeout(handleRejected, 0));
}
});
return newPromise;
}
三、静态方法
promise的静态方法为了处理多个promise对象,
all
:接收一个Promise
数组,当所有Promise
都成功时,返回一个包含所有结果的Promise
;只要有一个Promise
失败,就返回该失败的Promise
。race
:接收一个Promise
数组,只要有一个Promise
完成(成功或失败),就返回该Promise
的结果。
ini
static all(promises) {
return new MyPromise((resolve, reject) => {
const results = [];
let completedCount = 0;
if (promises.length === 0) {
resolve(results);
return;
}
promises.forEach((promise, index) => {
MyPromise.resolve(promise).then(
value => {
results[index] = value;
completedCount++;
if (completedCount === promises.length) {
resolve(results);
}
},
reason => {
reject(reason);
}
);
});
});
}
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach(promise => {
MyPromise.resolve(promise).then(
value => {
resolve(value);
},
reason => {
reject(reason);
}
);
});
});
}
}