🤖Promise
大纲
1.promise 简介
2.promise 解决的问题
3.promise 使用场景
4.promise API的使用
5.promise 关键问题
6.promise 自定义封装<构造函数-完整代码>
7.promise 自定义封装<class 类-完整代码>
🐽注:
本章是我对 promise 的总结;或有不对的地方,请各位 大佬 指出;感谢!
✍创作不易,如果本章帮助到了您,请给个👍哦;感谢!
🔖1.promise简介:
Promise是 JavaScript异步编程的一种解决方案。
它是 ES6 引入的一种原生对象,用来处理异步操作。传统的 JavaScript 异步编程使用的是回调函数,但回调函数容易导致代码可读性差、嵌套层次过深,甚至出现所谓的回调地狱。Promise的出现大大简化了这种情况,使异步代码的书写更加简洁、结构更清晰。
Promise的基本原理是,异步操作执行完后,Promise对象的状态会发生变化,并通知相应的处理函数来处理执行结果。Promise有三种状态:pending(等待),fulfilled(成功)和 rejected(失败)。一旦 Promise 进入 fulfilled 或 rejected 状态,就不能再改变状态。
💤2.promise 解决的问题
回调地狱:当多个异步操作需要按顺序执行时,嵌套的回调函数容易让代码变得难以理解和维护,导致所谓的回调地狱。
错误处理:传统的回调函数中,错误的捕获和处理机制复杂,容易出错。而Promise提供了统一的.catch()方法,可以捕获整个链条中的异常。
控制流程:使用回调函数难以控制异步操作的顺序和依赖,而Promise允许以链式方式进行流程控制,显著提升了代码的可读性。
2.1 什么是回调地狱:
是指在 JavaScript 中,使用多个嵌套的回调函数时,代码的可读性和可维护性大幅下降的现象。这种现象通常出现在异步编程中,尤其是处理多个异步操作时,导致代码层层嵌套,看起来像一个“金字塔”,因此得名“回调地狱”。
function step1(callback) {
setTimeout(() => {
console.log('Step 1 completed');
callback();
}, 1000);
}
function step2(callback) {
setTimeout(() => {
console.log('Step 2 completed');
callback();
}, 1000);
}
function step3(callback) {
setTimeout(() => {
console.log('Step 3 completed');
callback();
}, 1000);
}
// 回调地狱示例
step1(() => {
step2(() => {
step3(() => {
console.log('All steps completed');
});
});
});
代码解析:
1.每个步骤都是一个异步操作,完成后调用回调函数。
2.为了执行下一个步骤,需要在当前步骤的回调中调用下一个步骤的函数。
3.这导致了代码层层嵌套,难以阅读和维护。
回调地狱的缺点:
1.可读性差: 随着嵌套层级的增加,代码的可读性显著下降,难以理解逻辑。
2.调试困难: 错误通常会在深层嵌套的回调中被捕获,调试和处理错误变得更加复杂。
3.维护性差: 随着代码的增加,修改或重构的难度也增加
2.2 除了 promsie 还可以使用 async / await 来处理:
async function executeSteps() {
await step1();
await step2();
await step3();
console.log('All steps completed');
}
executeSteps();
💦3.promise 使用场景
网络请求:例如发送 Ajax 请求或使用 fetch API 获取数据,这类请求通常是异步操作,可以通过 Promise 处理请求的成功和失败。
定时任务:在使用 setTimeout 或 setInterval 等异步定时任务时,可以用 Promise 来确保代码按照期望的顺序执行。
文件读取:在浏览器中通过 FileReader 读取文件或在 Node.js 中进行文件系统操作时,往往需要处理异步的读取结果,Promise 可以使代码更加优雅。
👻4.promise_API 及 使用
4.1 Promise.prototype.then()
Promise.prototype.then(onResolve,onRejected);注册两个回调函数,分别处理成功和失败的情况。 then() 方法返回一个新的 Promise 对象,可以实现链式调用。
当 Promise 处于 "fulfilled"(已成功)状态时,p.then 的第一个回调函数(即 onResolve)会被执行。 当 Promise 处于 "rejected"(已失败)状态时,p.then 的第二个回调函数(即 onRejected),或者 p.catch 中的回调函数会被执行。
let p = new Promise((resolve, reject) => {
resolve('ok');
});
let res = p.then(v => {
console.log(v);// ok
}, reason => {
console.log(reason);
});
/*
res 的结果值 取决与 v=>{},reason=>{}的结果值;比如说 v=> new Promise((resolve, reject) =>{resolve('ok1')};那么res的结果值就是 返回的 promise 的结果值 ok1;
Promise.prototype.then 方法的返回值是一个新的 Promise。这个新的 Promise 的结果(状态和值)取决于 then 中回调函数的返回值。如果回调函数返回的是一个新的 Promise,那么 res 的结果会依赖于这个 Promise 的结果;如果回调函数返回的是一个普通值,那么 res 的 Promise 会被 resolve 为这个普通值。
*/
let res1 = p.then(v => new Promise((resolve, reject) => {
resolve('ok-2');
}))
console.log(res1);
/* 控制台打印 res1的结果:
Promise {<pending>}
[[Prototype]]: Promise
[[PromiseState]]: "fulfilled" // 状态
[[PromiseResult]]: "ok-2" // 结果值
*/
4.2 Promise.prototype.catch(onRejected)
Promise.prototype.catch(onRejected);只注册失败时的回调函数,等价于 then(null, onRejected)。用于处理 Promise 链条中的错误。
p.catch 等同于 p.then(null, onRejected),专门用来处理 Promise 被拒绝的情况。
let p = new Promise((resolve, reject) => {
// resolve('ok');
reject('error');
});
let res = p.catch(reason => {
console.log(reason);// error
});
// -catch 异常穿透
let p1 = new Promise((resolve, reject) => {
resolve('ok');
});
let res2 = p1.
then(v => {
console.log(111);
})
.then(v => {
console.log(v);//undefined
throw 'err';
}) // 这里抛出错误,Promise 链的状态变为 "rejected"
.then(v => {
console.log(333);
}) // 这个 then 不会执行,因为上一个 then 已经进入了 rejected 状态
.catch(reason => {
console.log(reason); // 捕获到错误,输出 'err'
});
/*
then 返回的都是一个新的Promise;
第一个 then(p1.then()):
执行 resolve('ok'),Promise 的状态变为 "fulfilled"。
第一个 then(v => { console.log(111); }) 被执行,输出 111。
没有返回值,因此返回 undefined 给下一个 then。
第二个 then: (then 返回的是一个新的 promise)
抛出错误 throw 'err',Promise 的状态变为 "rejected"。
从这一点开始,后续的 then 都会被跳过,直到有 catch 来捕获这个错误。
第三个 then:
由于前一个 then 抛出了错误,第三个 then 不会执行,因为 Promise 现在是 "rejected" 状态。
最后的catch:
这个 catch 捕获了前面抛出的错误 err,输出 'err'。
*/
console.log(res2, 'res2');
/* 控制打印 res2 的结果:
Promise {<pending>}
[[Prototype]]: Promise
[[PromiseState]]: "fulfilled"// p1 的状态
[[PromiseResult]]: undefined // 链式调用都没有返回值,默认返回 undefined,结果值也是 undefined
*/
4.3 Promise.prototype.finally(callback)
无论 Promise 最终状态是 fulfilled 还是 rejected,都会执行 finally 中的回调函数。
let p = new Promise((resolve, reject) => {
resolve('ok');
});
p.then(v => {
console.log(v);
}).finally(() => {
console.log('finally');
});
let p1 = new Promise((resolve, reject) => {
reject('error');
});
p1.catch(e => {
console.log(e);
}).finally(() => {
console.log('finally');
});
/*输出结果:
ok
error
finally
finally
*/
/* 结果说明
p.then(...) 和 p1.catch(...) 都是基于 Promise 的异步行为,这些回调会在所有同步代码执行完毕后,按照事件循环的机制进入微任务队列执行。
因为 p 和 p1 是独立的 Promise,它们的回调顺序相互独立,finally 的执行紧跟着它前面的 then 或 catch,没有干扰。
*/
4.4 Promise.resolve(value)
返回一个状态为 fulfilled 的 Promise,值为 value。
let p1 = Promise.resolve('ok');
console.log(p1, 'p1');// Promise {<fulfilled>: 'ok'}
let p2 = Promise.resolve(new Promise((resolve, reject) => {
resolve('ok1')
}));
console.log(p2, 'p2');// Promise {<fulfilled>: 'ok1'}
let p3 = Promise.resolve(new Promise((resolve, reject) => {
reject('error')
}));
console.log(p3, 'p3');
/*
Promise {<rejected>: 'error'}
Uncaught (in promise) error浏览器报错
*/
/* p3 详细说明
p3 = Promise.resolve(new Promise((resolve, reject) => { reject('error'); })):
p3 传入了一个新的 Promise,这个 Promise 被 reject,所以 p3 的状态变为 rejected,且会抛出一个未捕获的错误;
p3 的状态是 rejected,由于没有提供 .catch() 或者 .then() 的错误处理回调来捕获这个错误,浏览器会抛出 Uncaught (in promise) 错误。
*/
p3.catch(e => console.log(e))
/* 最终打印结果
Promise {<fulfilled>: 'ok'} 'p1'
Promise {<fulfilled>: 'ok1'} 'p2'
Promise {<rejected>: 'error'} 'p3'
error
*/
4.5 Promise.reject(peason)
返回一个状态为 rejected 的 Promise,理由为 reason
let p1 = Promise.reject('error');
p1.catch(e => {
console.log(e, 'p1');// error
});
let p2 = Promise.reject(new Promise((resolve, reject) => {
resolve('ok')
}));
console.log(p2, 'p2');
p2.catch(e => {
console.log(e, 'p2.catch');
})
/* 输出结果:
Promise {<rejected>: Promise} 'p2'
error p1
Promise {<fulfilled>: 'ok'}'p2.catch'
*/
/* 结果说明:
Promise {<rejected>: Promise} 'p2' 👉 p2 是接收了一个promise为参数,promise 是同步的;
error p1 👉 p1.catch 是异步的;所以 此打印结果不会出现在第一的位置;
Promise {<fulfilled>: 'ok'}'p2.catch' 👉 也是异步的并且排在 p1 的后面执行的;
p1------------------------------------------------------------------------:
p1 是一个通过 Promise.reject('error') 创建的立即被拒绝的 Promise,拒绝原因是 'error'。
p1.catch() 捕获了这个拒绝,并打印 error p1,所以你会看到 error p1 被打印。
p2------------------------------------------------------------------------:
p2 是通过 Promise.reject() 创建的拒绝状态的 Promise,但这次的拒绝原因是一个新的 Promise,即 new Promise((resolve, reject) => { resolve('ok'); })。
Promise.reject() 不会等待这个传递的 Promise 去解析,而是立即拒绝,并将整个 Promise 作为拒绝的原因。因此 p2 的状态是 rejected,其拒绝原因是一个 fulfilled 的 Promise。
当打印 p2 时,会看到 Promise {<rejected>: Promise},表示它是被拒绝的,原因是那个新建的 Promise。
p2.catch() 捕获到了 p2 的拒绝状态,这时 e 就是那个传递给 Promise.reject 的 Promise。
由于这个传递的 Promise 本身是被解析(fulfilled)的,所以当你打印 e 时,你会看到的是一个状态为 fulfilled 的 Promise,结果是 'ok'。
最终输出的是 Promise {<fulfilled>: 'ok'}。
*/
4.6 Promise.all([promise])
接受一个包含多个 Promise 对象的数组或可迭代对象,只有当所有 Promise 都 fulfilled 时,返回的 Promise 状态为 fulfilled,否则一旦有一个 Promise 被 rejected,返回的 Promise 状态为 rejected。
let p1 = Promise.reject('error');
let p2 = Promise.resolve('ok');
let p3 = new Promise((resolve, reject) => {
resolve('ok_1')
});
let res = Promise.all([p2, p3]);
console.log(res, 'res');
/* 控制台打印结果:
Promise {<pending>}
[[Prototype]]:Promise
[[PromiseState]]:'fulfilled'
[[PromiseResult]]:Array(2)
返回一个状态为 fulfilled 的 Promise,结果值为 Array;
*/
let resThen = res.then(v => {
console.log(v, 'resThen');// ['ok', 'ok_1'] 'resThen'
})
let res1 = Promise.all([p1, p2, p3]);
console.log(res1, 'res1'); // 控制台报错;原因是没有对 res1的结果进行 .then/.catch
let res2 = res1.then(v => {
console.log(v, 'res2-V');
}, r => { // 此时的 res1 的状态是 rejected,所以执行 r => {...}
console.log(r, 'res2-R');// 被捕获了到了
})
4.7 Promise.race([Promise])
和 Promise.all 类似,但是它会在第一个 Promise 结束(无论 fulfilled 还是 rejected)时结束。
let p1 = new Promise((resolve, reject) => {
resolve('ok_1');// 立即执行
});
let p2 = Promise.reject('error');
let p3 = Promise.resolve('ok');
console.log(p1, p2, p3);
let res = Promise.race([p1, p2, p3]);
res.then(
v => {
console.log(v, 'res') // ok_1 res
},
reason => {
console.log(reason, 'res');
}
);
/* 打印结果:
ok_1 res
*/
/* 说明
p1,p2,p3 执行顺序问题:
p1-------------------------------------:
p1 是通过 new Promise() 创建的,构造函数会同步执行,因此 resolve('ok_1') 立即执行,但 resolve 本身是异步的,会将回调加入微任务队列中等待执行。
p2-------------------------------------:
p2 是通过 Promise.reject('error') 创建的,Promise.reject() 立即返回一个状态为 rejected 的 Promise,并立即将这个拒绝的原因 'error' 加入微任务队列中。
p3-------------------------------------:
p3 是通过 Promise.resolve('ok') 创建的,它与 Promise.reject() 类似,Promise.resolve() 立即返回一个状态为 fulfilled 的 Promise,并将结果 'ok' 加入微任务队列中
*/
let p4 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok_p4') // 宏任务
})
});
let p5 = new Promise((resolve, reject) => {
reject('error_p5'); // 立即执行
});
let p6 = new Promise((resolve, reject) => {
resolve('ok_p6') // 立即执行
});
let res2 = Promise.race([p4, p5, p6]);
res2.then(v => {
console.log(v, 'res2');
}, reason => {
console.log(reason, 'res2');
})
/* 打印结果
error_p5 res2
*/
⛄5.promise 的几个关键问题:
5.1.promise的状态
promise的状态有三种:
1.pending<等待>
2.fulfilled<成功>
3.rejected<失败/拒绝>
5.2.可以改变promise状态的三种方式
1.promise的状态由
pending变为fulfilled
2.promise的状态由pending变为rejected
3.throw抛出错误 promise 的状态由pending变为rejected
Promise 的状态是
不可逆的,一旦Promise的状态由pending变为fulfilled/rejected,Promise的状态就不可在改变。这确保了异步操作的结果的一致且可信性;
5.3.promise 同步异步问题
let p = new Promise((resolve, reject) => {
resolve('ok');
console.log('111');
});
p.then(v => console.log('222'));
setTimeout(() => {
console.log('444');
});
console.log('333');
/* 输出结果:
'111' —— Promise 构造函数中的同步代码
'333' —— 同步代码
'222' —— then 中的回调,微任务
'444' —— setTimeout 回调,宏任务
*/
根据输出结果得知:
1. Promise 的构造函数是同步执行的。也就是说,当你创建一个 Promise 实例时,传递给它的执行器函数(executor,即 resolve 和 reject 所在的函数)会立即执行。
executor 等同Promise 接收的 (resolve, reject) => {}2. 虽然 Promise 构造函数是同步执行的,但 then、catch 等回调函数是异步执行的。它们会在当前的执行栈清空之后(即所有同步任务执行完毕后),被推入微任务队列(microtask queue)中等待执行。
5.4.错误传播机制
在
Promise链条中,如果某一个环节抛出错误,错误会沿着链条向下传播,直到被捕获为止。未捕获的错误会导致整个链条失败,但可以通过.catch()进行统一的错误处理。
证明:
不加 catch 进行捕获错误;
let p = new Promise((resolve, reject) => {
resolve('ok');
});
/*
p.then() 返回一个新的 Promise,其状态为 fulfilled,且结果是 上一个 promise返回的结果;
*/
//不写任何人东西,返回的 Promise 是成功状态且 结果值为 'ok';并且结果会传递给下一个 then
p.then()
.then(value => {
console.log('仔仔💓');
throw new Error('这里抛出了一个 🐖');
})
.then(value => {
console.log('崽崽💖');
})
// .catch(error => {
// console.log('error:', error.message);
// })
.then(() => {
console.log('代码走到了这里');
});
/* 控制台打印结果
仔仔💓
<Error>:Uncaught (in promise) Error: 这里抛出了一个 🐖(控制台直接报错)
*/
加上 catch 捕获错误:
let p = new Promise((resolve, reject) => {
resolve('ok');
});
/*
p.then() 返回一个新的 Promise,其状态为 fulfilled,且结果是 上一个 promise返回的结果;
*/
//不写任何人东西,返回的 Promise 是成功状态且 结果值为 'ok';并且结果会传递给下一个 then
p.then()
.then(value => {
console.log('仔仔💓'); // 仔仔💓'
throw new Error('这里抛出了一个 🐖');
})
.then(value => {
console.log('崽崽💖');
})
.catch(error => {
console.log('error:', error.message);
})
.then(() => {
console.log('代码走到了这里');
});
/* 控制台打印结果
仔仔💓
error: 这里抛出了一个 🐖
代码走到了这里
*/
释:
let p = new Promise((resolve, reject) => {
resolve('ok');
});
/*
p.then() 返回一个新的 Promise,其状态为 fulfilled,且结果是 上一个 promise返回的结果;
*/
//不写任何人东西,返回的 Promise 是成功状态且 结果值为 'ok';并且结果会传递给下一个 then
p.then()
.then(value => {
console.log('仔仔💓'); //控制台输出: 仔仔💓'
throw new Error('这里抛出了一个 🐖'); // 在此处抛出错误
})
.then(value => {
console.log('崽崽💖'); // 不会执行,因为上一个环节抛出了错误
})
.catch(error => {
console.log('error:', error.message); // 捕获并输出错误信息
})
.then(() => {
console.log('代码走到了这里'); // 依然可以继续执行
});
🎈6.promise 封装<构造函数-完整代码>
function Promise(executor) {
// 初始化状态
this.PromiseState = 'pending';
// 初始化结果值
this.PromiseResult = undefined;
// (异步时)保存回调函数
this.callbacks = [];
/**
* 状态、结果值、保存的回调函数 统一处理函数
* @param {String} state
* @param {any} data
*/
const handlerFn = (state, data) => {
// promise 的状态只能改变一次;
if (this.PromiseState !== 'pending') return;
this.PromiseState = state;
this.PromiseResult = data;
// 微任务
queueMicrotask(() => {
this.callbacks.forEach(callback => {
// 根据异步回来的状态 执行相应的函数
if (state === 'fulfilled') callback.onResolve(data);
if (state === 'rejected') callback.onRejected(data);
})
})
};
/**
* 状态成功所调用的函数
* @param {any} data
*/
const resolve = data => handlerFn('fulfilled', data);
/**
* 状态失败所调用的函数
* @param {any} data
*/
const reject = data => handlerFn('rejected', data);
// 使用 try catch 捕获错误;
try {
// 未捕获到错误则 执行器工作
executor(resolve, reject);
} catch (error) {
// 捕获到错误 promise的状态则为失败/拒绝
reject(error);
}
};
Promise.prototype.then = function (onResolve, onRejected) {
// 为 .then 补齐参数;
if (typeof onResolve !== 'function') onResolve = v => v;
// 实现 .catch 异常穿透的核心
if (typeof onRejected !== 'function') onRejected = r => { throw r };
// 返回一个 Promise
return new Promise((resolve, reject) => {
/**
* 统一处理函数
* @param {Function} callback
* @param {any} value
* @param {Function} resolve
* @param {Function} reject
*/
const handlerPromiseChange = (callback) => {
try {
// 结果值
let result = callback(this.PromiseResult);
// 结果值是否为一个 promise
if (result instanceof Promise) {
result.then(v => {
resolve(v);
}, r => {
reject(r);
});
} else {
// 否 执行 resolve 设置状态及结果值
resolve(result)
}
} catch (error) {
// 捕获到错误 则 promise 的状态为 rejected/失败/拒绝 值为error
reject(error);
}
};
// 异步
if (this.PromiseState === 'pending') {
// 异步时 保存回调函数;当Promise的状态改变之后再去执行对应的回调函数
this.callbacks.push({
onResolve: () => handlerPromiseChange(onResolve),
onRejected: () => handlerPromiseChange(onRejected),
})
};
// 同步 成功
if (this.PromiseState === 'fulfilled') {
// 微任务
queueMicrotask(() => {
handlerPromiseChange(onResolve);
})
};
// 同步 失败/拒绝
if (this.PromiseState === 'rejected') {
// 微任务
queueMicrotask(() => {
handlerPromiseChange(onRejected);
})
};
});
};
Promise.prototype.catch = function (onRejected) {
// 返回一个 promise,这里直接调用 then方法,并且值传递 失败/拒绝的处理 回调函数
return this.then(undefined, onRejected);
};
Promise.prototype.finally = function (callback) {
// finally 方法正确地在 then 和 catch 之后执行
return this.then(
v => Promise.resolve(callback()).then(() => v),
r => Promise.resolve(callback()).then(() => { throw r; })
);
}
Promise.resolve = function (value) {
//返回promise对象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
//状态设置为成功
resolve(value);
}
});
};
Promise.reject = function (reason) {
/*
返回一个状态为失败的 promise
*/
return new Promise((_, reject) => reject(reason));
};
Promise.race = function (promises) {
// 如果 promises 不是一个数组,报错提示;
if (!Array.isArray(promises)) throw TypeError('promises must be an Array');
// 返回一个 Promise
return new Promise((resolve, reject) => {
// 遍历 promises
promises.forEach(item => {
item.then(v=>{resolve(v)},r=>{reject(r)});
})
})
};
Promise.all = function (promises) {
// 如果 promises 不是一个数组,报错提示;
if (!Array.isArray(promises)) throw TypeError('promises must be an Array');
// 返回一个Promise
return new Promise((resolve, reject) => {
// 保存 promises数组 的每一项 promise成功的结果值;
let newArr = new Array(promises.length);
// 计算循环次数
let count = 0;
// 遍历 promises
promises.forEach((item, index) => {
item.then(v => {
newArr[index] = v;
count++;
if (count === promises.length) {
resolve(newArr);
}
}, r => {
reject(r)
})
})
})
};
🛸 7.Promise自定义封装<class 类-完整代码>
class Promise {
constructor(executor) {
// 初始化状态
this.PromiseState = 'pending';
// 初始化结果值
this.PromiseResult = undefined;
// (异步时)保存回调函数
this.callbacks = [];
/**
* 状态、结果值、保存的回调函数 统一处理函数
* @param {String} state
* @param {any} data
*/
const handlerFn = (state, data) => {
// promise 的状态只能改变一次;
if (this.PromiseState !== 'pending') return;
this.PromiseState = state;
this.PromiseResult = data;
// 微任务
queueMicrotask(() => {
this.callbacks.forEach(callback => {
// 根据异步回来的状态 执行相应的函数
if (state === 'fulfilled') callback.onResolve(data);
if (state === 'rejected') callback.onRejected(data);
});
});
};
/**
* 状态成功所调用的函数
* @param {any} data
*/
const resolve = (data) => handlerFn('fulfilled', data);
/**
* 状态失败所调用的函数
* @param {any} data
*/
const reject = (data) => handlerFn('rejected', data);
// 使用 try catch 捕获错误;
try {
// 未捕获到错误则 执行器工作
executor(resolve, reject);
} catch (error) {
// 捕获到错误 promise的状态则为失败/拒绝
reject(error);
}
}
then(onResolve, onRejected) {
// 为 .then 补齐参数;
if (typeof onResolve !== 'function') onResolve = (v) => v;
// 实现 .catch 异常穿透的核心
if (typeof onRejected !== 'function') onRejected = (r) => { throw r; };
// 返回一个 Promise
return new Promise((resolve, reject) => {
/**
* 统一处理函数
* @param {Function} callback
*/
const handlerPromiseChange = (callback) => {
try {
// 结果值
let result = callback(this.PromiseResult);
// 结果值是否为一个 promise
if (result instanceof Promise) {
result.then(resolve, reject);
} else {
// 否 执行 resolve 设置状态及结果值
resolve(result);
}
} catch (error) {
// 捕获到错误 则 promise 的状态为 rejected/失败/拒绝 值为error
reject(error);
}
};
// 异步
if (this.PromiseState === 'pending') {
// 异步时 保存回调函数;当Promise的状态改变之后再去执行对应的回调函数
this.callbacks.push({
onResolve: () => handlerPromiseChange(onResolve),
onRejected: () => handlerPromiseChange(onRejected),
});
}
// 同步 成功
if (this.PromiseState === 'fulfilled') {
// 微任务
queueMicrotask(() => {
handlerPromiseChange(onResolve);
});
}
// 同步 失败/拒绝
if (this.PromiseState === 'rejected') {
// 微任务
queueMicrotask(() => {
handlerPromiseChange(onRejected);
});
}
});
}
catch(onRejected) {
// 返回一个 promise,这里直接调用 then方法,并且值传递 失败/拒绝的处理 回调函数
return this.then(undefined, onRejected);
}
finally(callback) {
// finally 方法正确地在 then 和 catch 之后执行
return this.then(
(v) => Promise.resolve(callback()).then(() => v),
(r) => Promise.resolve(callback()).then(() => { throw r; })
);
}
static resolve(value) {
//返回promise对象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(resolve, reject);
} else {
//状态设置为成功
resolve(value);
}
});
}
static reject(reason) {
// 返回一个状态为失败的 promise
return new Promise((_, reject) => reject(reason));
}
static race(promises) {
// 如果 promises 不是一个数组,报错提示;
if (!Array.isArray(promises)) throw TypeError('promises must be an Array');
// 返回一个 Promise
return new Promise((resolve, reject) => {
// 遍历 promises
promises.forEach((item) => {
item.then(resolve, reject);
});
});
}
static all(promises) {
// 如果 promises 不是一个数组,报错提示;
if (!Array.isArray(promises)) throw TypeError('promises must be an Array');
// 返回一个Promise
return new Promise((resolve, reject) => {
// 保存 promises数组 的每一项 promise成功的结果值;
let newArr = new Array(promises.length);
// 计算循环次数
let count = 0;
// 遍历 promises
promises.forEach((item, index) => {
item.then((v) => {
newArr[index] = v;
count++;
if (count === promises.length) {
resolve(newArr);
}
}, reject);
});
});
}
}