手写PROMISE核心代码,提升JAVASCRIPT编程能力,加深JS异步任务理解,ES6必学知识
代码写在 HD.js 里
HD.js
class HD {
static PENDING = 'pending'; // 准备
static FUlFILLED = 'fulfilled'; // 解决
static REJECTED = 'rejected'; // 拒绝
constructor(executor) {
this.status = HD.PENDING;
this.value = null;
this.callbacks = [];
try {
executor(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
this.reject(error);
}
}
resolve(value) {
// 异步特性
if (this.status == HD.PENDING) {
this.status = HD.FUlFILLED;
this.value = value;
// 让与resolve同块的方法先执行
setTimeout(() => {
// 处理准备时期 then 放入的回调
this.callbacks.forEach(callback => {
callback['onFulfilled'](value);
})
})
}
}
reject(reason) {
// 异步特性
if (this.status == HD.PENDING) {
this.status = HD.REJECTED;
this.value = reason;
// 让与resolve同块的方法先执行
setTimeout(() => {
// 处理准备时期 then 放入的回调
this.callbacks.forEach(callback => {
callback['onRejected'](reason);
})
})
}
}
then(onFulfilled, onRejected) {
// 没传resolve方法
if (typeof onFulfilled != 'function') {
// then值穿透
onFulfilled = () => this.value;
}
// 没传reject方法
if (typeof onRejected != 'function') {
// 没有catch异常
onRejected = function () {
throw new Error("Unexpected end of input")
}
}
let promise = new HD((resolve, reject) => {
// 准备
if (this.status == HD.PENDING) {
this.callbacks.push({
onFulfilled: value => {
// 冗余代码的优化
HD.parse(promise, onFulfilled(value), resolve, reject)
},
onRejected: reason => {
// 冗余代码的优化
HD.parse(promise, onRejected(reason), resolve, reject)
}
});
}
// 处理
else if (this.status == HD.FUlFILLED) {
// 等待this.next赋值
setTimeout(() => {
// 冗余代码的优化
HD.parse(promise, onFulfilled(this.value), resolve, reject)
})
}
// 拒绝
else if (this.status == HD.REJECTED) {
// 等待this.next赋值
setTimeout(() => {
// 冗余代码的优化
HD.parse(promise, onRejected(this.value), resolve, reject)
})
}
});
return promise;
}
static parse(promise, result, resolve, reject) {
// 禁止同一个then中循环返回 promise
if (promise == result) {
throw new TypeError('Chaining cycle detected')
}
try {
// 设置结果值
if (result instanceof HD) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
}
static resolve(value) {
return new HD((resolve, reject) => {
HD.parse(null, value, resolve, reject);
})
}
static reject(value) {
return new HD((resolve, reject) => {
reject(value)
})
}
/** * 全成功,返回全部返回值 * 有失败,返回第一个失败信息 * @param {HD} promises */
static all(promises) {
return new HD((resolve, reject) => {
const values = [];
promises.forEach((promise) => {
promise.then(
value => {
values.push(value)
if (values.length == promises.length) {
resolve(values);
}
},
reason => {
reject(reason)
}
)
})
})
}
/** * race(竞赛) * 返回第一个返回值 * @param {HD} promises */
static race(promises) {
return new HD((resolve, reject) => {
promises.forEach(promise => {
promise.then(
value => {
return resolve(value);
},
reason => {
return reject(reason);
}
)
})
})
}
}
race测试代码(其他自行测试吧。。)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script src="./dist/HD.js"></script>
<script> let p1 = new HD((resolve, reject) => { resolve('p1') }) let p2 = new HD((resolve, reject) => { resolve('p2') }) HD.race([p1, p2]).then( value => { console.log('ok', value); }, reason => { console.log('error', reason) } ) // let p1 = new Promise((resolve, reject) => { // resolve('p1') // }) // let p2 = new Promise((resolve, reject) => { // reject('p2') // }) // Promise.race([p1, p2]).then( // value => { // console.log(value); // }, // // reason => { // // console.log(reason) // // } // ) </script>
</html>