ES5版本
/*
自定义Promise函数模块:IIFE
*/
(function(window){
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
/*
Promise构造函数
excutor:执行器函数(同步执行)
*/
function Promise (excutor) {
const self = this
self.status = PENDING //给promise对象指定status属性,初始值为pending
self.data = undefined //给promise对象指定一个用于存储结果数据的属性
self.callbacks = [] //每个元素的结构:{ onResolved() {}, onRejected() {} }
function resolve(value) {
// 如果当前状态不是pending,直接结束
if (self.status !== PENDING) return
// 将状态改为resolved
self.status = RESOLVED
// 保存value数据
self.data = value
// 如果有待执行callback函数,立即异步执行回调函数onResolved
if (self.callbacks.length > 0) {
setTimeout(() => { // 放入队列执行所有成功的回调
self.callbacks.forEach(callbacksObj => {
callbacksObj.onResolved(value)
});
})
}
}
function reject(reason) {
// 如果当前状态不是pending,直接结束
if (self.status !== PENDING) return
// 将状态改为rejected
self.status = REJECTED
// 保存reason
self.data = reason
// 如果有待执行callback函数,立即异步执行回调函数onRejected
if (self.callbacks.length > 0) {
setTimeout(() => { // 放入队列执行所有成功的回调
self.callbacks.forEach(callbacksObj => {
callbacksObj.onRejected(reason)
});
})
}
}
// 立即同步执行excutor
try {
excutor(resolve, reject)
} catch (error){ // 如果执行器抛出异常,promise对象变为rejected状态
reject(error)
}
}
/*
Promise原型对象的then
指定成功和失败的回调函数
返回一个新的promise对象
*/
Promise.prototype.then = function (onResolved, onRejected) {
// 指定默认的回调(实现错误/异常穿透的关键点)
onResolved = typeof onResolved === 'function' ? onResolved : value => value // 向后传递成功的value
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason } // 向后传递失败的reason
const self = this
// 返回一个新的promise对象
return new Promise((resolve, reject) => {
// 调用指定回调函数处理,根据执行结果,改变return的promise状态
function handle (callback) {
/*
1.如果抛出异常,return的promise就会失败,reason就是error
2.如果返回的不是promise,return的promise就会成功,result就是返回的值
3.如果返回的是promise,return的promise的结果就是这个promise的结果
*/
try {
const result = callback(self.data)
if (result instanceof Promise) {
/* result.then(
value => resolve(value),
reason => reject(reason)
) */
result.then(resolve, reject)
} else {
resolve(result)
}
} catch (error) {