// 定义Promise的三种状态常量
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
function MyPromise(executor) {
this.status = PENDING // 默认的时候的PENDING
this.value = null // 成功时候的值
this.reason = null // 失败时候的值
this.onResolvedCallbacks = [] // 成功时候的回调
this.onRejectedCallbacks = [] // 失败时候的回调
let _this = this;
// 内部的resolve方法
function resolve(value) {
if (_this.status === PENDING) {
// 改变Promise状态,设置值
_this.value = value
_this.status = FULFILLED
// 若是异步的情况下,需要调用它原来then中传入的函数
_this.onResolvedCallbacks.forEach(fn => fn())
}
}
// 内部的reject方法
function reject(reason) {
// 改变Promise状态,设置值
if (_this.status === PENDING) {
_this.reason = reason
_this.status = REJECTED
// 若是异步的情况下,需要调用它原来then中传入的函数
_this.onRejectedCallbacks.forEach(fn => fn())
}
}
try {
// 执行Promise内的代码
executor(resolve, reject)
} catch (error) {
// 执行中有错误的话捕捉
reject(error)
}
}
function resolvePromise(promise2, x, resolve, reject) {
// 如果promise2, x和相等,那么就循环引用了,表示两个永远等不到结果(resolve/reject)
if (promise2 === x) {
reject(new Error('循环引用'))
return;
}
let called = false; // 避免多次调用
if (typeof x != null && (typeof x === 'function' || typeof x === 'object')) {
try {
let then = x.then;
if (typeof then === 'function') { // 如果x.then是一个函数(有可能包含在对象属性中不是函数),调用该then方法,
then.call(x, y => {
// y有可能也是Promise,所以还需要继续resolvePromise
if(called) return;
called = true;
resolvePromise(promise2, y, resolve, reject);
}, reason => {
reject(reason);
})
} else {
//x是一个对象,也可以直接resolve
if(called) return;
called = true;
resolve(x)
}
} catch (error) {
if(called) return;
called = true;
reject(error)
}
} else {
// 如果x是普通值的情况可以直接resolve
resolve(x)
}
}
MyPromise.prototype.then = function (onFulfilled, onRejected) {
// 如果传入的onFulfilled, onRejected不是一个函数的话,那么要转换成函数,用于在链式调用时能获得上一个相同的值
onFulfilled = onFulfilled === 'function' ? onFulfilled : value => value
onRejected = onRejected === 'function' ? onRejected : reason => reason
let _this = this;
// PromiseA+规范中写明: then方法必须返回一个新的Promise
let promise2 = new MyPromise(function (resolve, reject) {
if (_this.status === PENDING) {
// 如果调用then方法的时候,此时Promise的状态还是PENDING的话,那么把then中的两个回调函数传到内部的数组中存放
// ,等到调用resolve/reject方法的时候再执行里面的代码
_this.onResolvedCallbacks.push(function () {
let x = onFulfilled(_this.value)
resolvePromise(promise2, x, resolve, reject)
})
_this.onRejectedCallbacks.push(function () {
let x = onRejected(_this.reason)
resolvePromise(promise2, x, resolve, reject)
})
} else if (_this.status === FULFILLED) {
// 此时Promise的状态是FULFILLED的话,那么直接调用传入的onFulfilled方法就行
let x = onFulfilled(_this.value)
// 1. 由于then中需要返回一个Promise,那么这个Promise要怎样才能被resolve或reject呢?
// 2. 如果调用onFulfilled的返回值x也是一个Promise怎么办
// 通过实现一个resolvePromise的方法来解决他们之间的resolve或者reject的问题。
resolvePromise(promise2, x, resolve, reject)
} else if (_this.status === REJECTED) {
// 此时Promise的状态是REJECTED的话,那么直接调用传入的onRejected方法就行
let x = onRejected(_this.reason)
// 1. 由于then中需要返回一个Promise,那么这个Promise要怎样才能被resolve或reject呢?
// 2. 如果调用onRejected的返回值x也是一个Promise怎么办
// 通过实现一个resolvePromise的方法来解决他们之间的resolve或者reject的问题。
resolvePromise(promise2, x, resolve, reject)
}
})
return promise2;
}
module.exports = MyPromise
实现一个基本的Promise
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 1.当代种种事件不同于历史之处,在于我们不知道它们会产生什么后果。 2.经验和利益的偶然结合,往往会向人们揭示...