// 工具函数 handleValue 来专门处理实例方法 then 返回的值(类型的判断以及对应的处理)
const handleValue = (promise2, x, resolve, reject) => {
// 循环引用,自己等待自己完成,会出错,用reject传递出错误原因
if (promise2 === x) {
return reject(new TypeError('检测到Promise的链式循环引用'))
}
// 为了判断resolve过的就不用再reject了(比如有reject和resolve的时候),确保递归解析中只传递出去一次值
let once = false;
//如果x不是null,是对象或者方法
if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
// 防止重复去读取x.then
let then = x.then;
// 判断x是不是Promise
if (typeof then === 'function') {
// 是promise,call他,第一个参数指定x这个promise对象作为then方法的this上下文,所以then方法中的this来自自己的promise对象x
// 调用then实例方法处理Promise执行结果
then.call(x, y => {
if (once) return;
once = true;
// 防止Promise中Promise执行成功后又传递一个Promise过来,要做递归解析。
// handleValue(promise2, y, resolve, reject);
resolve(y) // 结果当作promise2的resolve结果,此时resolve中的this指向promise2
}, r => {
if (once) return;
once = true;
// 一次错误就直接返回
reject(r); // 失败原因当作promise2的reject失败原因,此时reject中的this指向promise2
})
} else {
// 如果x是个普通对象,直接调用resolve(x)
resolve(x);
}
} catch (err) {
if (once) return;
once = true;
reject(err);
}
} else {
// 如果x是个原始值,直接调用resolve(x)
resolve(x);
}
}
// 在这里用Symbol定义三种状态,防止外部改变状态
const Pending = Symbol('Pending'); // 进行中
const Fulfilled = Symbol('Fulfilled'); // 已成功
const Rejected = Symbol('Rejected'); // 已失败
class Promise {
constructor(executor) {
this.status = Pending; //存储 Promise 的状态
this.value = undefined; //存储executor函数中业务代码执行成功的结果
this.reason = undefined; //存储executor函数中业务代码执行失败的原因
this.onFulfilled = []; //executor函数中业务代码执行成功回调函数的集合
this.onRejected = []; //executor函数中业务代码执行失败回调函数的集合
const resolve = value => {
// Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected
// 只有当状态为 Pending 才会改变,来保证一旦状态改变就不会再变。
if (this.status === Pending) {
this.status = Fulfilled;
this.value = value;
// 依次调用成功回调函数
this.onFulfilled.forEach(fn => fn());
}
};
const reject = value => {
// 只有当状态为 Pending 才会改变,来保证一旦状态改变就不会再变。
if (this.status === Pending) {
this.status = Rejected;
this.reason = value;
// 依次调用失败回调函数
this.onRejected.forEach(fn => fn());
}
};
try {
//将resolve和reject两个函数作为参数传入executor
executor(resolve, reject);
} catch (error) {
//如果在函数中抛出异常则将它注入reject中
reject(error)
}
}
// PS: 1、then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例),
// 第一个参数是fulfilled(已成功)状态的回调函数,第二个参数(可选)是rejected(已失败)状态的回调函数
// 因此可以采用链式写法,即then方法后面再调用另一个then方法。
// 2、用 try ... catch 语句来捕获错误,把错误用内置方法传递出去 reject,防止 Promise 内部执行错误无法追踪
then(onFulfilled, onRejected) {
//解决onFufilled,onRejected没有传值的问题,实现then值的穿透
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) {
// 由于原生的 Promise 是V8引擎提供的微任务,我们无法还原V8引擎的实现,
// 所以这里使用 setTimeout 模拟异步,所以原生的Promise.then()是微任务,这里是宏任务。
setTimeout(() => {
try {
// 因为有的时候需要判断then中的方法是否返回另一个promise对象(即有异步操作),
// 这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用,
// 所以需要判断,如果返回值为promise对象,则需要取出结果当作promise2的resolve结果
// 如果不是,直接作为promise2的resolve结果
let x = onFulfilled(this.value);
// 抽离出一个公共方法来判断他们是否为promise对象
handleValue(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0)
}
if (this.status === Rejected) {
if (onRejected && typeof onRejected === 'function') {
setTimeout(() => {
try {
let x = onRejected(this.reason);
handleValue(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0)
}
}
if (this.status === Pending) {
// 添加订阅者,观察者模式解决异步调用问题(控制 then 实例方法中回调函数的执行时机)
this.onFulfilled.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
handleValue(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0)
})
if (onRejected && typeof onRejected === 'function') {
this.onRejected.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
handleValue(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0)
})
}
}
})
return promise2
}
// //catch方法
// catch(onRejected) {
// this.then(null, onRejected)
// }
//finally方法
// finally(callback) {
// let P = this.constructor;
// return this.then(
// value => P.resolve(callback()).then(() => value),
// reason => P.resolve(callback()).then(() => { throw reason })
// );
// }
// static resolve(param) {
// if (param instanceof Promise) {
// return param;
// }
// return new Promise((resolve, reject) => {
// if (
// param &&
// Object.prototype.toString.call(param) === '[object Object]' &&
// typeof param.then === 'function'
// ) {
// setTimeout(() => {
// param.then(resolve, reject)
// }, 0)
// } else {
// resolve(param)
// }
// })
// }
// static reject(param) {
// return new Promise((resolve, reject) => {
// reject(param)
// })
// }
// static all(promises) {
// //将参数promises转为一个真正的数组
// promises = Array.from(promises);
// return new Promise((resolve, reject) => {
// const length = promises.length;
// let value = [];
// if (length) {
// value = Array.apply(null, {
// length: length
// })
// for (let i = 0; i < length; i++) {
// Promise.resolve(promises[i]).then(
// res => {
// value[i] = res;
// if (value.length == length) {
// resolve(value);
// }
// },
// err => {
// reject(err)
// return;
// }
// )
// }
// } else {
// resolve(value)
// }
// })
// }
// static race(promises) {
// //将参数promises转为一个真正的数组
// promises = Array.from(promises);
// return new Promise((resolve, reject) => {
// const length = promises.length;
// if (length) {
// for (let i = 0; i < length; i++) {
// Promise.resolve(promises[i]).then(
// res => {
// resolve(res);
// return;
// },
// err => {
// reject(err)
// return;
// }
// )
// }
// } else {
// return
// }
// })
// }
}
const test = new Promise((resolve, reject) => {
resolve('"执行成功"')
})
test.then(res => {
console.log(res)
})
console.log(Object.prototype.toString.call(test))