按照Promise/A+ 规范实现代码(promisesaplus.com/) Promise类实现:
const RESOLVED = "RESOLVED";
const REJECTED = "REJECTED";
//因为所有的promise都遵循这个规范 。规定这里写法应该兼容所有promise
const resolvePromise = (promise2, x, resolve, reject) => {
//判断x 的值 和promise2 是不是同一个 如果是同一个 就不要再等待了 直接出错即可
if(promise2 === x) {
return reject(new TypeError('Chaning cycle .....'))
}
//判断数据类型 typeof constructor instanceof toString
if(typeof x === 'object' && x !== null || typeof x === 'function' ) {
let called; // 内部测试的时候 会成功和失败都调用
try {
let then = x.then //取then有可能这个then属性是通过defineProperty来定义的
if(typeof then === 'function') { //当前有then方法 姑且认为x是promise
then.call(x, y => { // 能保证不用再次取then的值
if(called) {
return
}
called = true //防止多次调用成功和失败
resolvePromise(promise2, x, resolve, reject) // 采用promise的成功结果 向下传递
}, r => {
if(called) {
return
}
called = true //防止多次调用成功和失败
reject(r) // 采用promise的成功结果 向下传递
})
}
else {
resolve(x) // 说明x是一个普通的对象 直接成功即可
}
} catch (error) {
//promise失败了 有可能还能调用成功
if(called) {
return
}
called = true //防止多次调用成功和失败
reject(error)
}
}
else {
// x 是一个普通值
resolve(x) //直接让promise2成功即可
}
}
class Promise {
constructor(executor) {
//executor 执行器
this.status = PENDING; //默认等待状态
this.value = undefined; //成功的值
this.reason = undefined; // 失败的原因
this.onResolvedCallbacks = []; //成功的回调的数组
this.onrejectedCallbacks = []; //失败的回调的数组
//成功的函数
const resolve = (value) => {
if (this.status === PENDING) {
this.status = RESOLVED;
this.value = value;
this.onResolvedCallbacks.forEach((fn) => fn()); //发布
}
};
//失败的原因
const 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); //如果执行器发生错误 也调用reject
}
}
then(onfulfilled, onrejected) { //then 目前有两个参数
// onfulfilled onrejected 是可选参数
onfulfilled = typeof onfulfilled === 'function' ? onfulfilled : val => val
onrejected = typeof onrejected === 'function' ? onrejected : err => {
throw err
}
let promise2 = new Promise((resolve, reject) => { //executor 会立刻执行
//同步的时候
if (this.status === RESOLVED) {
setTimeout(() => {
try {
let x = onfulfilled(this.value);
// resolve(x)
// x可能是普通值,也可能是promise
// 判断x的值 => promise2的状态
resolvePromise(promise2, x, resolve, reject)
} catch (error) {
reject(error)
}
}, 0)
}
if (this.status === REJECTED) {
setTimeout(() => {
let x = onrejected(this.reason);
// resolve(x)
// x可能是普通值,也可能是promise
// 判断x的值 => promise2的状态
resolvePromise(promise2, x, resolve, reject)
}, 0)
}
//如果是异步就先订阅好
if (this.status === PENDING) {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
let x = onfulfilled(this.value);
// resolve(x)
// x可能是普通值,也可能是promise
// 判断x的值 => promise2的状态
resolvePromise(promise2, x, resolve, reject)
}, 0)
});
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
let x = onrejected(this.reason);
// resolve(x)
// x可能是普通值,也可能是promise
// 判断x的值 => promise2的状态
resolvePromise(promise2, x, resolve, reject)
}, 0)
});
}
})
return promise2
}
}
// --------------------------
Promise.defer = Promise.deferred = function() {
let dfd = {}
dfd.promise = new Promise((resolve,reject) => {
dfd.resolve = resolve
dfd.reject = reject
})
return dfd
}
module.exports = Promise;