Promise(期约)扩展方法实现
代码实现
前面的章节中我们的PromisePolyfill
类实现了Promise(期约)
的基本模型,下面介绍一下其静态扩展方法resolve
、reject
、all
、allSettle
、race
、any
的实现。
class PromisePolyfill {
constructor(executor) {
//...
}
//该函数一旦执行,将内部的这两个回调函数赋值
then(onFulfilled, onRejected) {
//...
}
//注意这个catch捕获的是最后一个reject
catch(onRejected) {
//...
}
static resolve(res) {
return new PromisePolyfill((resolve, reject) => {
resolve(res);
});
}
static reject(reason) {
return new PromisePolyfill((resolve, reject) => {
reject(reason);
});
}
static all(promiseArray) {
return new PromisePolyfill((resolve, reject) => {
const values = [];
promiseArray.forEach((promise) => {
promise
.then((res) => {
values.push(res);
if (values.length === promiseArray.length) resolve(values);
})
.catch((err) => {
reject(err);
});
});
});
}
static allSettle(promiseArray) {
return new PromisePolyfill((resolve, reject) => {
const results = [];
promiseArray.forEach((promise) => {
promise
.then((res) => {
results.push({ status: PROMISE_STATUS_FULFILLED, result: res });
if (results.length === promiseArray.length) resolve(results);
})
.catch((err) => {
results.push({ status: PROMISE_STATUS_REJECTED, result: err });
if (results.length === promiseArray.length) resolve(results);
});
});
});
}
static race(promiseArray) {
return new PromisePolyfill((resolve, reject) => {
promiseArray.forEach((promise) => {
promise.then(resolve, reject);
});
});
}
static any(promiseArray) {
// 要执行resolve必须等到有一个成功的结果
// 要执行reject所有的都失败才执行reject
return new PromisePolyfill((resolve, reject) => {
let rejectArr = [];
promiseArray.forEach((promise) => {
promise.then(resolve, (err) => {
rejectArr.push(err);
if (rejectArr.length === promiseArray.length) {
reject(new Error('all promises reject'));
}
});
});
});
}
}
测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script src="./index.js"></script>
<script>
PromisePolyfill.resolve('PromisePolyfill.resolve').then(res => {
console.log(res);
})
PromisePolyfill.reject('PromisePolyfill.reject').then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
PromisePolyfill.all([new PromisePolyfill((resolve,reject) => {
resolve(123)
}),new PromisePolyfill((resolve,reject) => {
resolve(456)
}) ]).then(res => {
// console.log(res);
})
PromisePolyfill.allSettle([new PromisePolyfill((resolve,reject) => {
resolve(123)
}),new PromisePolyfill((resolve,reject) => {
reject(456)
})]).then(res => {
// console.log(res);
})
PromisePolyfill.race([new PromisePolyfill((resolve,reject) => {
resolve(456)
}),new PromisePolyfill((resolve,reject) => {
resolve(123)
})]).then(res => {
// console.log(res);
})
PromisePolyfill.any([new PromisePolyfill((resolve,reject) => {
reject(456)
}),new PromisePolyfill((resolve,reject) => {
reject(123)
})]).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
</script>
</body>
</html>