Promises/A+规范是一个开放、健全且通用的 JavaScript Promise 标准
//promise内部有三种状态
const PENDING = 'pending';
const FULLFILLED = 'fullfilled';
const REJECTED = 'rejected';
class Promise {
//解析x,x可能的值:promise, thanble对象和普通值;promise对象和thenable对象需要特殊处理
static resolvePromise(promise2, x, resolve, reject) {
if(promise2 === x) {
//每次返回的是个新的promise,不能返回原来的promise,否则报错
return reject(new TypeError('Chaining cycle detected for promise'));
}
let called = false; //防止被多次调用
if(x instanceof Promise) {
//x是个promise
x.then(value => {
//这里返回的仍然可能是promise
if(called) return;
called = true;
Promise.resolvePromise(promise2, value, resolve, reject);
}, reason => {
if(called) return;
called = true;
reject(reason)
})
}else if(x !== null && typeof x === 'object' || typeof x == 'function') {
try {
const then = x.then;
if(typeof then == 'function') {
//如果x是thenable对象
const res = then.call(x, (value) => {
if(called) return;
called = true;
Promise.resolvePromise(promise2, value, resolve, reject);
}, (reason) => {
if(called) return;
called = true;
reject(reason)
});
}else {
//不是thenable对象,是个普通的对象。直接resolve
if(called) return;
called = true;
resolve(x)
}
}catch(e) {
if(called) return;
called = true;
reject(e)
}
}else {
//x为一个普通值
resolve(x)
}
}
constructor(executor) {
//检测executor类型
if(typeof executor !== 'function') {
throw new TypeError(`Promise resolver ${executor} is not a function`)
}
this.executor = executor;
this.status = PENDING;
this.result = undefined;
this.reason = undefined;
this.onFullfilledCallbacks = [];
this.onRejectedCallbacks = [];
this.resolve = (result) => {
if(this.status !== PENDING) return;
this.status = FULLFILLED;
this.result = result;
this.onFullfilledCallbacks.forEach(fn => fn(this.result))
};
this.reject = (reason) => {
if(this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn(this.reason))
};
try {
executor(this.resolve, this.reject);
}catch(e) {
this.reject(e);
}
}
then(successHandler, rejectHandler) {
if(typeof successHandler !== 'function') {
successHandler = s => s
}
//注意:这里是直接抛出错误,因为rejectHandler如果不是函数,就相当于没有处理这个错误,错误继续传递
if(typeof rejectHandler !== 'function') {
rejectHandler = reason => {throw reason}
}
let promise2 = new Promise((resolve, reject) => {
//实现链式调用
if(this.status === FULLFILLED) {
queueMicrotask(() => {
try {
const x = successHandler(this.result);
// resolve(x)
Promise.resolvePromise(promise2, x, resolve, reject)
}catch(e) {
reject(e)
}
})
}
if(this.status === REJECTED) {
queueMicrotask(() => {
try {
const x = rejectHandler(this.reason);
Promise.resolvePromise(promise2, x, resolve, reject)
}catch(e) {
reject(e)
}
})
}
if(this.status === PENDING) {
//这里如果此时状态还是PENDING,需要先把处理函数存储起来,储存的时候注意要放在微任务中执行
this.onFullfilledCallbacks.push((result) => {
queueMicrotask(() => {
try {
const x = successHandler(result);
Promise.resolvePromise(promise2, x, resolve, reject)
}catch(e) {
reject(e)
}
})
});
this.onRejectedCallbacks.push((reason) => {
queueMicrotask(() => {
try {
const x = rejectHandler(reason);
Promise.resolvePromise(promise2, x, resolve, reject)
}catch(e) {
reject(e)
}
})
});
}
})
return promise2;
}
}