手写promise
function PromiseN(excute){
//初始化状态
this.status = 'pending';
//状态成功时的值, resolve的参数
this.value = null;
//状态失败时的值, reject的参数
this.reason = null;
//连续调用(非链式调用)-存储onFulfilled / onRejected 的数组
this.onFulfilledArray = [];
this.onRejectedArray = [];
const resolve = (data) => {
//模拟微任务
queueMicrotask(() => {
if(this.status === 'pending'){
//改变状态和状态对应的值
this.status = 'fulfilled';
this.value = data;
//循环调用储存的onFulfilled方法
this.onFulfilledArray.forEach(fn => fn());
}
})
};
const reject = (err) => {
//模拟微任务
queueMicrotask(() => {
if(this.status === 'pending'){
this.status = 'rejected';
this.reason = err;
//循环调用储存的onRejected方法
this.onRejectedArray.forEach(fn => fn());
}
})
};
try{
excute(resolve, reject);
}catch(err){
throw new Error(err);
}
}
PromiseN.prototype.then = function(onFulfilled, onRejected) {
//onFulFilled / onRejected 必须是函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (data) => { {return data};
onRejected = typeof onRejected === 'function' ? onRejected : (err) => { return err};
if(this.status === 'fulfilled'){
//链式调用then方法, 需要返回promise
return new PromiseN((resolve, reject) => {
queueMicrotask(() => {
try{
const result = onFulfilled(this.value);
resolve(result);
}catch(err){
reject(err);
}
})
})
}
if(this.status === 'rejected'){
//链式调用then方法, 需要返回promise
return new PromiseN((resolve, reject) => {
queueMicrotask(() => {
try{
const result = onRejected(this.reason);
reject(result);
}catch(err){
reject(err);
}
})
})
}
if(this.status === 'pending'){
//链式调用then方法, 需要返回promise
return new PrmomiseN((resolve, reject) => {
this.onFulfilledArray.push(() => {
try{
const result = onFulfilled(this.value);
resolve(result);
}catch(err){
reject(err);
}
});
this.onRejectedArray.push(() => {
try{
const result = onReject(this.reason);
reject(result);
}catch(err){
reject(err);
}
})
})
}
}
如果then中返回值为对象 / 函数 / promise需特殊处理
简单实现Promise.all
function PromiseAll(arr){
return new Promise((resolve, reject) => {
const len = arr.length;
let data = [];
let count = 0;
for(let i = 0; i < len; i++){
Promise.resolve(arr[i]).then(value => {
data[i] = value;
//promise全部调用完成后,返回一个结果的数组
if(++count === len ){
resolve(data);
}
}).catch(reject)
//当一个promise失败时, 立即结束返回错误
}
})
}
简单实现Promise.race
function PromiseRace(arr){
return new Promise((resolve, reject) => {
for(let i = 0; i < arr.length; i++){
//当一个promise成功或失败时就返回结果, 所有的promise方法依然会执行弹不会对结果做处理
Promise.resolve(arr[i]).then(resolve, reject);
}
})
}
简单实现中断promise
function PromiseWrap(p1){
let abort;
const p2 = () => new Promise((resolve, reject) => {
abort = reject;
})
//Promise.race当一个promise成功或失败时就返回结果, 通过结束添加的promise来中断当前pending状态的所有promise
let pw = Promise.race([p1, p2()]);
//抛出reject方法,主动结束promise
pw.abort = abort;
return pw;
}
生成多个promise
const promiseArrGenerator = (num) => new Array(num).fill(0).map((item,index) => () => new Promise((resolve, reject) => setTimeout(() => { reolve(index) }, Math.random() * 1000)))
const promiseArr = promiseArrGenerator(10);
顺序调用
const promiseChain = (promiseArr) => {
//then返回值是内部的返回值
promiseArr.reduce((pre,curr) => pre.then(data => {
//按位取反, 去除初始值
~data && console.log(data);
return curr();
}),Promise.resolve(-1)).then(data => {
conosle.log(data);
})
}
并发调用并限制并发个数
function promisePipe(promiseArr, num){
if(promiseArr.length <= num){
Promise.all(promiseArr.map(fn => fn())).then(data => console.log(data));
return;
}
let _promiseArr = [...promiseArr];
//并发调用num个
for(let i = 0; i < num; i++){
run(_promiseArr.shift());
}
function run(p){
p().then(data => {
console.log(data);
//递归调用,当一个调用完成,就执行下一个
if(_promiseArr.length) run(_promiseArr.shift());
});
}
}