一、resolve和reject类方法
- 定义类的静态方法
static resolve(value) {
return new MyPromise(resolve => resolve(value))
}
static reject(reason) {
return new MyPromise((resolve, reject) => reject(reason))
}
MyPromise.resolve('resolve message').then(res => {
console.log(res);
});
MyPromise.reject('reject message').catch(err => {
console.log(err);
});
二、all和allSettled类方法
前面:
const p1 = new MyPromise(resolve => {
setTimeout(() => {
resolve('111111p')
}, 1000)
});
const p2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
reject('2222p')
}, 2000)
});
const p3 = new MyPromise(resolve => {
setTimeout(() => {
resolve('3333p')
}, 3000)
});
2.1. all
- 什么时候执行resolve,什么时候执行reject?
- 当所有promise有结果了resolve了,就调用resolve;
- 当执行过程中出现reject,那么就调用reject;
static all(promises) {
const values = [];
return new MyPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(res => {
const newLegh = values.push(res);
if (newLegh === promises.length) {
resolve(values);
}
}, err => {
reject(err);
});
});
});
}
MyPromise.all([p1, p2, p3]).then(res => {
console.log('res: ', res);
}).catch(err => {
console.log('err: ', err);
});
2.2. allSettled
- 不管执行过程中走了resolve还是reject都需要执行完才resolve;
static allSettled(promises) {
return new MyPromise(resolve => {
const results = [];
promises.forEach(promise => {
promise.then(res => {
results.push({ status: STATUS_FUFILLED, value: res });
if (results.length === promises.length) {
resolve(results)
};
}, err => {
results.push({ status: STATUS_REJECTED, reason: err });
if (results.length === promises.length) {
resolve(results)
};
});
});
});
}
MyPromise.allSettled([p1, p2, p3]).then(res => {
console.log('res: ', res);
});
三、race和any类方法
3.1. race
- 谁先有结果,那么就使用谁的结果;
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(resolve, reject);
});
});
}
const p1 = new MyPromise(resolve => {
setTimeout(() => {
resolve('111111p')
}, 1000)
});
const p2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
reject('2222p')
}, 800)
});
const p3 = new MyPromise(resolve => {
setTimeout(() => {
resolve('3333p')
}, 2000)
});
MyPromise.race([p1, p2, p3]).then(res => {
console.log('res: ', res);
}).catch(err => {
console.log('err: ', err);
});
3.2. any
- any方法会等到一个fulfilled状态,才会决定新Promise的状态;
- 如果所有的Promise都是reject的,那么会报一个AggregateError的错误;
static any(promises) {
return new MyPromise((resolve, reject) => {
const reasons = [];
promises.forEach(promise => {
promise.then(res => {
resolve(res);
}, err => {
reasons.push(err);
if (reasons.length === promises.length) {
reject(new AggregateError(reasons));
}
});
});
});
}
const p1 = new MyPromise((resolve, reject) => {
setTimeout(() => {
reject('111111p')
}, 1000)
});
const p2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
reject('2222p')
}, 800)
});
const p3 = new MyPromise((resolve, reject) => {
setTimeout(() => {
reject('3333p')
}, 2000)
});
MyPromise.any([p1, p2, p3]).then(res => {
console.log('res: ', res);
}).catch(err => {
console.log('err: ', err);
console.log('err: ', err.errors);
});
3.3. 完整代码
const STATUS_PENDING = 'pending';
const STATUS_FUFILLED = 'fulfilled';
const STATUS_REJECTED = 'rejected';
function execFnWithCatchErr(execFn, value, resolve, reject) {
try {
const result = execFn(value);
resolve(result);
} catch (err) {
reject(err);
}
};
class MyPromise {
constructor(executor) {
this.state = STATUS_PENDING;
this.value = undefined;
this.reason = undefined;
this.onFufilledFns = [];
this.onRejectedFns = [];
const resolve = (value) => {
if (this.state === STATUS_PENDING) {
queueMicrotask(() => {
if (this.state !== STATUS_PENDING) return;
this.state = STATUS_FUFILLED;
this.value = value;
this.onFufilledFns.forEach(fn => {
fn(this.value)
});
});
}
}
const reject = (reason) => {
if (this.state === STATUS_PENDING) {
queueMicrotask(() => {
if (this.state !== STATUS_PENDING) return;
this.state = STATUS_REJECTED;
this.reason = reason;
this.onRejectedFns.forEach(fn => {
fn(this.reason)
});
});
}
}
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then(onFufilled, onRejected) {
const defaultOnRejected = err => { throw err };
onRejected = onRejected || defaultOnRejected;
const defaultOnFulfilled = value => { return value };
onFufilled = onFufilled || defaultOnFulfilled;
return new MyPromise((resolve, reject) => {
if (this.state === STATUS_FUFILLED && onFufilled) {
execFnWithCatchErr(onFufilled, this.value, resolve, reject)
};
if (this.state === STATUS_REJECTED && onRejected) {
execFnWithCatchErr(onRejected, this.reason, resolve, reject)
};
if (this.state === STATUS_PENDING) {
if (onFufilled) this.onFufilledFns.push(() => {
execFnWithCatchErr(onFufilled, this.value, resolve, reject)
});
if (onRejected) this.onRejectedFns.push(() => {
execFnWithCatchErr(onRejected, this.reason, resolve, reject)
});
}
})
}
catch(onRejected) {
return this.then(undefined, onRejected);
}
finally(onFinally) {
this.then(() => {
onFinally()
}, () => {
onFinally()
})
}
static resolve(value) {
return new MyPromise(resolve => resolve(value));
}
static reject(reason) {
return new MyPromise((resolve, reject) => reject(reason));
}
static all(promises) {
return new MyPromise((resolve, reject) => {
const values = [];
promises.forEach(promise => {
promise.then(res => {
const newLegh = values.push(res);
if (newLegh === promises.length) {
resolve(values);
}
}, err => {
reject(err);
});
});
});
}
static allSettled(promises) {
return new MyPromise(resolve => {
const results = [];
promises.forEach(promise => {
promise.then(res => {
results.push({ status: STATUS_FUFILLED, value: res });
if (results.length === promises.length) {
resolve(results)
};
}, err => {
results.push({ status: STATUS_REJECTED, reason: err });
if (results.length === promises.length) {
resolve(results)
};
});
});
});
}
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(resolve, reject);
});
});
}
static any(promises) {
return new MyPromise((resolve, reject) => {
const reasons = [];
promises.forEach(promise => {
promise.then(res => {
resolve(res);
}, err => {
reasons.push(err);
if (reasons.length === promises.length) {
reject(new AggregateError(reasons));
}
});
});
});
}
};
四、其它
相关文章:Promise中的类方法