手写 Promise
业界比较著名的实现 Promise 的类库有 bluebird、Q、ES6-Promise
写 Promise,一般遵循 Promise/A+规范。
// 发布订阅模式
const PENDING = 'PENDING';
const FULFILLED = 'FULILLED';
const REJECTED = 'REJECTED';
const resolvePromise = (promise2, x, resolve, reject) => {
if (promise2 === x) {
return reject(new Error('Chaining cycle detected for promise #<Promise>'))
}
let called;
if ((typeof x === 'object' && x != null) || typeof x === function) {
try {
let then = x.then;
if (typeof then === 'function') {
then.call(x, y => {
if (called) {
return ;
}
called = true;
resolvePromise(promise2, y, resolve, reject);
}, r => {
if (called) {
return ;
}
called = true;
reject(r);
})
} else {
resolve(x);
}
} catch (e) {
if (called) {
return;
}
called = true;
reject(e)
}
} else {
resolve(x);
}
}
class Promise {
constructor(executor) {
this.status = PENDING; // 默认状态
this.value = undefined;
this.reason = undefined;
// 存放成功的回调
this.onResolvedCallbacks = [];
// 存放失败的回调
this.onRejectedCallbacks= [];
let resolve = (value) => {
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
// 依次将对应的函数执行
this.onResolvedCallbacks.forEach(fn=>fn());
}
}
let reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
// 依次将对应的函数执行
this.onRejectedCallbacks.forEach(fn=>fn());
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
then(onFulfilled, onRejected) {
//解决 onFufilled,onRejected 没有传值的问题
//Promise/A+ 2.2.1 / Promise/A+ 2.2.5 / Promise/A+ 2.2.7.3 / Promise/A+ 2.2.7.4
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
//因为错误的值要让后面访问到,所以这里也要跑出个错误,不然会在之后 then 的 resolve 中捕获
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err };
let promise2 = new Promise((resolve, reject) => {
if (this.status === FULFILLED) {
onFulfilled(this.value)
setTimeout(() => {
try {
let x = onFulfiled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}
}, 0)
}
if (this.status === PENDING) {
// 如果promise的状态是 pending,
// 需要将 onFulfilled 和 onRejected 函数存放起来,
// 等待状态确定后,再依次将对应的函数执行
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0)
});
// 如果promise的状态是 pending,
// 需要将 onFulfilled 和 onRejected 函数存放起来,
// 等待状态确定后,再依次将对应的函数执行
this.onRejectedCallbacks.push(()=> {
seTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0)
})
}
});
}
}