手写 promise
Promise 的特点
- 执⾏了 resolve,Promise 状态会变成 fulfilled;
- 执⾏了 reject,Promise 状态会变成 rejected;
- Promise 状态不可逆,第⼀次成功就永久为 fulfilled,第⼀次失败就永远状态为 rejected;
- Promise 中有 throw 的话,就相当于执⾏了 reject;
Promise 实现思路
实现 resolve 和 reject
Promise 的初始状态是 pending
需要对 resolve 和 reject 绑定 this:确保 resolve 和 reject 的 this 指向永远指向当前的 MyPromise 实例,防⽌随着函数执⾏环境的改变⽽改变;Promise 有三种状态, 并且状态不可变
pending:等待中,是初始状态;
fulfilled:成功状态;
rejected:失败状态;
⼀旦状态从 pending 变为 fulfilled 或者 rejected,那么此 Promise 实例的状态就不可以改变了then 的特点实现
then 接收两个回调,⼀个是成功回调,⼀个是失败回调;
当 Promise 状态为 fulfilled 执⾏成功回调,为 rejected 执⾏失败回调;
如 resolve 或 reject 在定时器⾥,则定时器结束后再执⾏ then;
then ⽀持链式调⽤,下⼀次 then 执⾏受上⼀次 then 返回值的影响;定时器的实现;保证 Promise 中 then 的回调在 setTimeout 后执行
Promise 代码模拟实现
javascript
class MyPromise {
// 构造⽅法
constructor(executor) {
// 初始化值
this.initValue();
// 初始化this指向
this.initBind();
try {
// 执⾏传进来的函数
executor(this.resolve, this.reject);
} catch (e) {
// 捕捉到错误直接执⾏reject
this.reject(e);
}
}
initBind() {
// 初始化this
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
}
initValue() {
// 初始化值
this.PromiseResult = null; // 终值
this.PromiseState = "pending"; // 状态
this.onFulfilledCallbacks = []; // 保存成功回调
this.onRejectedCallbacks = []; // 保存失败回调
}
resolve(value) {
// state是不可变的
if (this.PromiseState !== "pending") return;
// 如果执⾏resolve,状态变为fulfilled
this.PromiseState = "fulfilled";
// 终值为传进来的值
this.PromiseResult = value;
// 执⾏保存的成功回调
while (this.onFulfilledCallbacks.length) {
this.onFulfilledCallbacks.shift()(this.PromiseResult);
}
}
reject(reason) {
// state是不可变的
if (this.PromiseState !== "pending") return;
// 如果执⾏reject,状态变为rejected
this.PromiseState = "rejected";
// 终值为传进来的reason
this.PromiseResult = reason;
// 执⾏保存的失败回调
while (this.onRejectedCallbacks.length) {
this.onRejectedCallbacks.shift()(this.PromiseResult);
}
}
then(onFulfilled, onRejected) {
// 接收两个回调 onFulfilled, onRejected
// 参数校验,确保⼀定是函数
onFulfilled =
typeof onFulfilled === "function" ? onFulfilled : (val) => val;
onRejected =
typeof onRejected === "function"
? onRejected
: (reason) => {
throw reason;
};
var thenPromise = new MyPromise((resolve, reject) => {
const resolvePromise = (cb) => {
// 使⽤setTimeout代替微任务,这一步为了实现:then执⾏顺序
setTimeout(() => {
try {
const x = cb(this.PromiseResult);
if (x === thenPromise) {
throw new Error("不能返回⾃身。。。");
}
if (x instanceof MyPromise) {
// 如果返回值是promise对象,返回值为成功,新promise就是成功
// 如果返回值是promise对象,返回值为失败,新promise就是失败
// 谁知道返回的promise是失败成功?只有then知道
x.then(resolve, reject);
} else {
// ⾮Promise就直接成功
resolve(x);
}
} catch (err) {
// 处理报错
reject(err);
throw new Error(err);
}
});
};
if (this.PromiseState === "fulfilled") {
// 如果当前为成功状态,执⾏第⼀个回调
resolvePromise(onFulfilled);
} else if (this.PromiseState === "rejected") {
// 如果当前为失败状态,执⾏第⼆个回调
resolvePromise(onRejected);
} else if (this.PromiseState === "pending") {
// 如果状态为待定状态,暂时保存两个回调
// 如果状态为待定状态,暂时保存两个回调
this.onFulfilledCallbacks.push(resolvePromise.bind(this, onFulfilled));
this.onRejectedCallbacks.push(resolvePromise.bind(this, onRejected));
}
});
// 返回这个包装的Promise
return thenPromise;
}
}
Promise.all
- 接收⼀个 Promise 数组,数组中如有⾮ Promise 项,则此项当做成功;
- 如果
所有 Promise 都成功,则返回成功结果数组
; - 如果
有⼀个 Promise 失败,则返回这个失败结果
;
javascript
static all(promises) {
const result = [];
let count = 0;
return new MyPromise((resolve, reject) => {
const addData = (index, value) => {
result[index] = value;
count++;
if (count === promises.length) resolve(result);
};
promises.forEach((promise, index) => {
if (promise instanceof MyPromise) {
promise.then(
(res) => {
addData(index, res);
},
(err) => reject(err)
);
} else {
addData(index, promise);
}
});
});
}
Promise.race
- 接收⼀个 Promise 数组,数组中如有⾮ Promise 项,则此项当做成功;
- 哪个
Promise 最快得到结果,就返回那个结果,⽆论成功失败
;
javascript
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach((promise) => {
if (promise instanceof MyPromise) {
promise.then(
(res) => {
resolve(res);
},
(err) => {
reject(err);
}
);
} else {
resolve(promise);
}
});
});
}
Promise.any
- 只要参数实例
有一个变成fulfilled状态
,包装实例就会变成 fulfilled 状态; - 如果
所有参数实例都变成rejected状态
,包装实例就会变成 rejected 状态
javascript
static any(promises) {
return new Promise((resolve, reject) => {
let count = 0;
promises.forEach((promise) => {
promise.then(
(val) => {
resolve(val);
},
(err) => {
count++;
if (count === promises.length) {
reject(new AggregateError("All promises were rejected"));
}
}
);
});
});
}
Promise.allSettled
- 只有等到参数数组的
所有 Promise 对象都发生状态变更
(不管是 fulfilled 还是 rejected),返回的 Promise 对象才会发生状态变更
js
function allSettled(promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
throw new TypeError("argument must be a array");
}
const result = [];
promises.forEach((promise, index) => {
promise.then(
(value) => {
result[index] = {
status: "fulfilled",
value,
};
},
(reason) => {
result[index] = {
status: "rejected",
reason,
};
}
);
});
});
}