<!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>promise A+ 规范</title>
</head>
<body>
<script>
let a = `每一个异步场景都可以看做是一个任务,这个任务分为两个阶段 三个状态
unsettled 未决阶段 settled 已决阶段 pending 等待 fulfilled 成功态 rejected 失败态`;
let b = `各个阶段和各个状态间不可逆转,状态始终是由 pending => fulfilled 或 rejected`;
let c = `将任务由未决的 pending 状态推向已决的fulfilled状态,这个行为叫做 resolve;推向已决的rejected状态,这个行为叫 reject;`;
let d = `每个异步任务必须提供一个then方法来处理成功后的数据或失败后的原因;then方法规定了有两个参数, onFulfilled onRejected`;
</script>
<script>
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
// promise是一个类,他接受一个函数作为参数
class myPromise {
constructor(executor) {
this.status = PENDING;
this.dispatchers = [];
this.data = null;
this.reason = null;
try {
executor(this.__resolve.bind(this), this.reject.bind(this));
} catch (err) {
this.__reject(err);
}
}
__updataStatus(newStatus) {
if (this.status !== PENDING) return;
this.status = newStatus;
}
__resolve(data) {
this.__updataStatus(FULFILLED);
this.data = data;
this.__executeDispatchers();
}
__executeDispatchers({ dispatcher, status }) {
if (this.status === PENDING) return;
for (const dispatcherConf of dispatchers) {
this.__executeDispatcher(dispatcherConf);
}
}
__executeDispatcher({ dispatcher, status, resolve, reject }) {
if (this.status !== status) {
return;
}
if (typeof dispatcher !== 'function') {
this.status === FULFILLED ? resolve(this.data) : reject(this.data);
return;
}
// dispatcher已经是一个函数了
try {
const result = dispatcher(this.status === FULFILLED ? this.data : this.reason); // 如果是fulfilled 我们就把 data 传进去,如果是 rejected 我们就要把 reason 传进去;
resolve(result);
} catch (err) {
reject(err);
}
}
__reject(reason) {
this.__updataStatus(REJECTED);
this.reason = reason;
this.__executeDispatchers();
}
then(onFulfilled, onRejected) {
return new myPromise((resolve, reject) => {
this.dispatchers.push(
{
status: FULFILLED,
dispatcher: onFulfilled,
reject,
resolve
},
{
status: REJECTED,
dispatcher: onRejected,
reject,
resolve
}
);
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
}
const myPro = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(111);
}, 1000);
});
myPro.then().then(r => {
console.log('r', r);
});
</script>
</body>
</html>