本文仅作为个人记录,文中可能存在不严谨的地方。
要了解更多可以看下这两篇文章:
史上最易读懂的 Promise/A+ 完全实现
promise/A+规范翻译以及手写实现
Promise/A+ 的标准有哪些?
-
只有一个 then 方法,没有 catch、race、all 等方法。
-
then 返回一个新的 Promise。
-
不同的 Promise 的实现需要相互调用。
-
Promise 的状态有 pending、fullfilled、rejected 三种。初始状态是 pending ,可以由 pending 转化为 fullfilled 或者 rejected。一旦状态确定之后,不能再被改变。
-
更具体的官方标准,看这里。
下面上代码
function MyPromise(executor) {
const _this = this;
// 状态
_this.status = 'pending';
// resolve 值
_this.value = null;
// reject 原因
_this.reason = null;
// resolve、reject 函数
_this.onFullfilled = [];
_this.onRejected = [];
function resolve(value) {
if (value instanceof MyPromise) {
return value.then(resolve, reject);
}
// 其实这里采用 setTimeout 方式实现异步执行 onFullfilled/onRejected 不太符合 Event Loop 机制。下面 reject 同理。
setTimeout(() => {
// 只有状态为 pending 才能被改变
if (_this.status == 'pending') {
_this.value = value;
_this.status = 'resolved';
_this.onFullfilled.forEach(currentValue => currentValue(value));
}
}, 0);
}
function reject(reason) {
setTimeout(() => {
// 只有状态为 pending 才能被改变
if (_this.status == 'pending') {
_this.reason = reason;
_this.status = 'rejected';
_this.onRejected.forEach(currentValue => currentValue(reason));
}
}, 0);
}
// 注意:若执行过程出现异常,则捕获异常并执行 reject 函数。
try {
executor(resolve, reject)
} catch (e) {
reject(e);
}
}
function resolvePromise(promise2, x, resolve, reject) {
let then;
let thenCallorThrow = false;
if (promise2 === x) {
return reject(new TypeError('same Promise!'))
}
if (x instanceof MyPromise) {
if (x.status === 'pending') {
x.then(value => {
resolvePromise(promise2, value, resolve, reject)
}, reject)
} else {
x.then(resolve, reject)
}
return
}
if ((x !== null) && ((typeof x === 'object') || (typeof x === 'function'))) {
try {
then = x.then;
if (typeof then === 'function') {
then.call(x, res => {
if (thenCallorThrow) return;
thenCallorThrow = true;
return resolvePromise(promise2, res, resolve, reject);
}, err => {
if (thenCallorThrow) return;
thenCallorThrow = true;
return reject(err)
})
} else {
resolve(x);
}
} catch (e) {
if (thenCallorThrow) return;
thenCallorThrow = true;
return reject(e)
}
} else {
return resolve(x)
}
}
MyPromise.prototype.then = function (onFullfilled, onRejected) {
const _this = this;
let promise2; // promise.then() 返回一个 promise 对象
// Promise 值的穿透处理:
// 场景如: new Promise(resolve => resolve('abc')).then().catch().then(res => {console.log('print abc')})
onFullfilled = typeof onFullfilled === 'function' ? onFullfilled : val => val;
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err };
switch (_this.status) {
case 'pending':
promise2 = new MyPromise((resolve, reject) => {
_this.onFullfilled.push(value => {
try {
let x = onFullfilled(value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}
});
_this.onRejected.push(reason => {
try {
let x = onRejected(reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}
});
})
case 'resolved':
promise2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
try {
let x = onFullfilled(_this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}
});
})
case 'rejected':
promise2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
try {
let x = onRejected(_this.reason);
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
});
})
default:
break;
}
return promise2;
}
// Promise 标准里面没有 catch、race、all 等方法,只有一个 then 方法
MyPromise.prototype.catch = function (onRejected) {
return this.then(null, onRejected)
}
new MyPromise((resolve, reject) => {
resolve('right');
}).then(res => {
console.log(res)
}, err => {
console.warn(err)
})
网友评论