Promise 思维导图
1. resolve与reject
Promise
的初始状态是pendingresolve
和reject
的this指向永远指向当前的MyPromise实例,防止随着函数执行环境的改变而改变代码
class MyPromise {
constructor(executor) {
this.initValue(); //初始化值
this.initBind(); //初始化this指向
executor(this.resolve, this.reject); //执行传进的函数
}
initBind() {
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
}
initValue() {
this.promiseState = "pending";
this.promiseResult = null;
}
resolve(value) {
this.promiseState = "fulfilled";
this.promiseResult = value;
}
reject(reason) {
this.promiseState = "rejected";
this.promiseResult = reason;
}
}
测试
```javascript const test1 = new MyPromise((resolve, reject) => { resolve(“ok”); }); test1;
const test2 = new MyPromise((resolve, reject) => { reject(“no”); }); test2;
<a name="SDpJD"></a>
# 2. 状态只可变一次
```javascript
resolve(value) {
if (this.PromiseState !== "pending") return;
this.promiseState = "fulfilled";
this.promiseResult = value;
}
reject(reason) {
if (this.PromiseState !== "pending") return;
this.promiseState = "rejected";
this.promiseResult = reason;
}
3. throw
有抛出错误就等于执行 reject,用 try catch 包裹一下
constructor(executor) {
this.initValue(); //初始化值
this.initBind(); //初始化this指向
try {
executor(this.resolve, this.reject); //执行传进的函数
} catch (e) {
this.reject(e);
}
}
4. then
- then接收两个回调,一个是成功回调,一个是失败回调
- 当Promise状态为fulfilled执行成功回调,为rejected执行失败回调
- 如resolve或reject在定时器里,则定时器结束后再执行then
- then支持链式调用,下一次then执行受上一次then返回值的影响
then(onFulfilled, onRejected) {
// 参数校验,确保一定是函数
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : val => val;
// console.log(onFulfilled);
onRejected =
typeof onRejected === "function"
? onRejected
: reason => {
throw reason;
};
if (this.promiseState === "fulfilled") {
// 如果当前为成功状态,执行第一个回调
onFulfilled(this.promiseResult);
} else if (this.promiseState === "rejected") {
// 如果当前为失败状态,执行第二哥回调
onRejected(this.promiseResult);
}
}
const test = new MyPromise((resolve, reject) => {
resolve("ok");
}).then(
res => console.log(res),
err => console.log(err)
);
//ok
5. 定时器
如何保证有定时器的情况下,到规定的时间再执行回调?
我们可以正常执行 then 但是等到规定时间之后在执行 then 的回调
- 怎么知道要执行回调 —— 怎么知道什么时候定时器结束 —— pending 状态转变为其他状态的时候
- 一个 promise 可能有多个 then —— 用数组存
initValue() {
this.promiseState = "pending";
this.promiseResult = null;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
}
resolve(value) {
if (this.promiseState !== "pending") return;
this.promiseState = "fulfilled";
this.promiseResult = value;
while (this.onFulfilledCallbacks.length) {
this.onFulfilledCallbacks.shift()(this.promiseResult);
}
}
reject(reason) {
if (this.promiseState !== "pending") return;
this.promiseState = "rejected";
this.promiseResult = reason;
while (this.onRejectedCallbacks.length) {
this.onRejectedCallbacks.shift()(this.promiseResult);
}
}
then(onFulfilled, onRejected) {
// 参数校验,确保一定是函数
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : val => val;
// console.log(onFulfilled);
onRejected =
typeof onRejected === "function"
? onRejected
: reason => {
throw reason;
};
if (this.promiseState === "fulfilled") {
// 如果当前为成功状态,执行第一个回调
onFulfilled(this.promiseResult);
} else if (this.promiseState === "rejected") {
// 如果当前为失败状态,执行第二哥回调
onRejected(this.promiseResult);
} else if (this.promiseState === "pending") {
//状态仍是 pending,先保存
this.onFulfilledCallbacks.push(onFulfilled.bind(this));
this.onRejectedCallbacks.push(onRejected.bind(this));
}
}
测试
const test2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve("成功"); // 1秒后输出 成功
// resolve('成功') // 1秒后输出 失败
}, 1000);
}).then(
res => console.log(res),
err => console.log(err)
);
6. 链式调用
下一次then
执行受上一次then
返回值的影响
then
方法本身会返回一个新的Promise
对象- 如果返回值是
promise
对象,返回值为成功,新promise
就是成功 - 如果返回值是
promise
对象,返回值为失败,新promise
就是失败 - 如果返回值非
promise
对象,新promise
对象就是成功,值为此返回值
then(onFulfilled, onRejected) {
// 参数校验,确保一定是函数
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : val => val;
// console.log(onFulfilled);
onRejected =
typeof onRejected === "function"
? onRejected
: reason => {
throw reason;
};
const thenPromise = new MyPromise((resolve, reject) => {
const resolvePromise = cb => {
try {
const x = cb(this.promiseResult);
if (x === thenPromise) {
throw new Error("不能返回自身");
}
if (x instanceof MyPromise) {
x.then(resolve, reject);
} else {
//不是 promise 对象
resolve(x);
}
} catch (e) {
reject(e);
throw new Error(e);
}
};
if (this.promiseState === "fulfilled") {
// 如果当前为成功状态,执行第一个回调
resolvePromise(onFulfilled);
} else if (this.promiseState === "rejected") {
// 如果当前为失败状态,执行第二个回调
resolvePromise(onRejected);
} else if (this.promiseState === "pending") {
//状态仍是 pending,先保存
this.onFulfilledCallbacks.push(resolvePromise.bind(this, onFulfilled));
this.onRejectedCallbacks.push(resolvePromise.bind(this, onRejected));
}
});
return thenPromise;
}
}
7. 微任务
8. all
- 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
- 如果所有Promise都成功,则返回成功结果数组
如果有一个Promise失败,则返回这个失败结果
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);
}
});
});
}
9. race
接收一个
Promise
数组,数组中如有非Promise
项,则此项当做成功哪个
Promise
最快得到结果,就返回那个结果,无论成功失败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);
}
});
});
}
10. allSettled
接收一个Promise数组,数组中如有非Promise项,则此项当做成功
把每一个Promise的结果,集合成数组,返回
static allSettled(promises) {
return new Promise((resolve, reject) => {
const res = [];
let count = 0;
const addData = (status, value, i) => {
res[i] = {
status,
value,
};
count++;
if (count === promises.length) {
resolve(res);
}
};
promises.forEach((promise, i) => {
if (promise instanceof MyPromise) {
promise.then(
res => {
addData("fulfilled", res, i);
},
err => {
addData("rejected", err, i);
}
);
} else {
addData("fulfilled", promise, i);
}
});
});
}
11. any
any 就是 all 的反过来
接收一个
Promise
数组,数组中如有非Promise
项,则此项当做成功- 如果有一个
Promise
成功,则返回这个成功结果 - 如果所有
Promise
都失败,则报错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"));
}
}
);
});
});
}