(function (window) {
const PENDING = 'pending' // 初始化未确定状态
const RESOLVED = 'resolved' // 成功的状态
const REJECTED = 'rejected' // 失败的状态
function Promise(actuator) {
// 当前Promise实例
const self = this
// 初始化实例的状态: pending resolved rejected
self.status = PENDING
// 存储数据, 初始为undefined
self.data = undefined
// 存储promise对象的回调函数
self.callbacks = []
/*
改变promise状态,指定成功的value
*/
function resolve(value) {
/*
promise的状态的改变只能改变一次
*/
// 判断当前promise状态, 只有pending状态调用resolve才会生效
if (self.status !== PENDING) return
// 改变promise的状态
self.status = RESOLVED
// 存储成功的数据
self.data = value
// 异步调用所有缓存待执行成功的回调函数
if (self.callbacks.length > 0) { // 缓存的回调函数的数组里面有回调函数
// 异步执行,指定成功的回调函数
setTimeout(() => {
self.callbacks.forEach(callbacksObj=>{ // 遍历callbacks
callbacksObj.onResolved(self.data) // 执行成功的回调, 并将成功的数据传递给指定成功的回调
})
});
}
}
/*
改变promise状态,指定失败的reason
*/
function reject(reason) {
/*
promise的状态的改变只能改变一次
*/
// 判断当前promise状态, 只有pending状态调用reject才会生效
if (self.status !== PENDING) return
// 改变promise的状态
self.status = REJECTED
// 存储失败的数据
self.data = reason
// 异步调用所有缓存待执行失败的回调函数
if (self.callbacks.length > 0) { // 缓存的回调函数的数组里面有回调函数
// 异步执行,指定失败的回调函数
/*
真正的promise不是使用的setTimeout,因为promise的异步任务是微队列的任务,使用setTimeout模拟
*/
setTimeout(() => {
self.callbacks.forEach(callbacksObj=>{ // 遍历callbacks
callbacksObj.onRejected(self.data) // 执行失败的回调, 并将失败的数据传递给指定失败的回调
})
});
}
}
// 捕获执行器异常
try {
// 调用执行器函数来启动异步任务
actuator(resolve, reject)
} catch (error) {
// 执行器出现异常,调用reject,改变promise状态 pending ==> rejected
reject(error)
}
}
/*
用来指定成功或失败的回调函数
1) 如果当前的promise是resolved状态, 异步执行成功的回调函数onResolved
2) 如果当前的promise是rejected状态, 异步执行成功的回调函数onRejected
3) 如果当前的promise是pending状态, 保存回调函数
返回一个新的promise对象------(返回的新的promise的状态,是由onResolved或onRejected执行的结果决定)
2.1) (onResolved或onRejected)抛出error ==> 新promise的状态变为rejected, 结果值为error
2.2) (onResolved或onRejected)返回值不是promise ==> 新promise的状态变为resolved, 结果值为(onResolved或onRejected)返回值
2.3) (onResolved或onRejected)返回值是promise ==> (onResolved或onRejected)返回的promise的结果决定then返回的promise的状态
*/
Promise.prototype.then = function (onResolved, onRejected) {
// 保存调用then方法的promise对象
const self = this
// 如果没有指定失败的回调函数,将失败的值向下传递
onRejected = typeof onRejected === 'function' ? onRejected : (reason) => {throw reason}
// 如果没有指定成功的回调函数,将成功的值向下传递
onResolved = typeof onResolved === 'function' ? onResolved : value => value
// 返回一个promise对象
return new Promise((resolve,reject)=>{
// 调用成功或失败的回调函数, 根据执行的结果改变then方法返回的promise的状态
function handle(callback) {
try {
const result = callback(self.data)
if (result instanceof Promise) { // 2.3) (onResolved或onRejected)返回值是promise
result.then( // 通过result这个promise成功或失败的结果来决定then方法返回的promise的状态
value => resolve(value),
reason => reject(reason)
)
// 上面三行代码的简写
// result.then(resolve, reject)
}else{ // 2.2) (onResolved或onRejected)返回值不是promise
resolve(result)
}
} catch (error) {
// 2.1) (onResolved或onRejected)抛出error
reject(error)
}
}
// 1)
if (self.status === RESOLVED) { // 调用then方法的promise对象的状态为resolved,
//异步执行成功的回调函数onResolved
setTimeout(() => {
/*
try {
// 接收onResolved成功的回调的返回值, 来决定then方法返回的promise的状态
const result = onResolved(self.data)
if (result instanceof Promise) { // 2.3) (onResolved或onRejected)返回值是promise
result.then( // 通过result这个promise成功或失败的结果来决定then方法返回的promise的状态
value => resolve(value),
reason => reject(reason)
)
// 上面三行代码的简写
// result.then(resolve, reject)
}else{ // 2.2) (onResolved或onRejected)返回值不是promise
resolve(result)
}
} catch (error) {
// 2.1) (onResolved或onRejected)抛出error
reject(error)
}
*/
handle(onResolved)
});
// 2)
}else if (self.status === REJECTED) { // 调用then方法的promise对象的状态为rejected,
// 异步执行成功的回调函数onRejected
setTimeout(() => {
/*
try {
const result = onRejected(self.data)
if (result instanceof Promise) { // 2.3) (onResolved或onRejected)返回值是promise
result.then((resolve,reject)=>{ // 通过result这个promise成功或失败的结果来决定then方法返回的promise的状态
value => resolve(value),
reason => reject(reason)
})
// result.then(resolve, reject)
}else{
// 2.2) (onResolved或onRejected)返回值不是promise
resolve(result)
}
} catch (error) {
// 2.1) (onResolved或onRejected)抛出error
reject(error)
}
*/
handle(onRejected)
});
// 3)
} else{ // 调用then方法的promise对象的状态为pending, 保存回调函数
/* // 保存回调函数 ---> 当前promise对象里面
// callbacks里面的回调函数是由执行resolve或reject方法调用的
this.callbacks.push({ // 将2个回调函数以对象的显示保存到promise实例上
onResolved,
onRejected
}) */ // 使用此方法保存成功或失败的回调函数,在resolve或reject执行的时候,去执行这2个函数,没办法修改then方法返回的新的promise的状态
this.callbacks.push({ // 不直接保存失败或成功的回到函数, 保存的是包含回调函数调用的函数
onResolved (value){ //注意: 调用callbacks里面的成功或是失败的回调都是在resolve函数或reject函数里面执行的,所以这里不许要异步执行成功或失败的回调函数
// onResolved(value)
/*
try {
// 接收onResolved成功的回调的返回值, 来决定then方法返回的promise的状态
const result = onResolved(self.data)
if (result instanceof Promise) { // 2.3) (onResolved或onRejected)返回值是promise
result.then( // 通过result这个promise成功或失败的结果来决定then方法返回的promise的状态
value => resolve(value),
reason => reject(reason)
)
// 上面三行代码的简写
// result.then(resolve, reject)
}else{ // 2.2) (onResolved或onRejected)返回值不是promise
resolve(result)
}
} catch (error) {
// 2.1) (onResolved或onRejected)抛出error
reject(error)
}
*/
handle(onResolved)
},
onRejected (reason){ // 此处的参数可以不用接收
// onRejected(reason)
/*
try {
const result = onRejected(self.data)
if (result instanceof Promise) { // 2.3) (onResolved或onRejected)返回值是promise
result.then((resolve,reject)=>{ // 通过result这个promise成功或失败的结果来决定then方法返回的promise的状态
value => resolve(value),
reason => reject(reason)
})
// result.then(resolve, reject)
}else{
// 2.2) (onResolved或onRejected)返回值不是promise
resolve(result)
}
} catch (error) {
// 2.1) (onResolved或onRejected)抛出error
reject(error)
}
*/
handle(onRejected)
}
})
}
})
}
/*
用来指定失败回调函数的方法
catch是then的语法糖
*/
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
/*
返回一个promise对象(返回的promise对象,可能是失败的可能是成功的)
value可能是一个一般的值, 也可能是一个promise对象
*/
Promise.resolve = function (value) {
return new Promise((resolve,reject)=>{
if (value instanceof Promise) {
value.then(resolve, reject)
}else{
resolve(value)
}
})
}
/*
返回一个失败状态的promise对象
*/
Promise.reject = function (reason) {
return new Promise((resolve,reject)=>{
reject(reason)
})
}
Promise.all = function (promises) {
return new Promise((resolve, reject)=>{
// 遍历所有promise, 取所有的结果
let results = new Array(promises.length) // 保存成功的promise数据的数组
let resultCount = 0 // 已经成功的promise数量
promises.forEach((p, index)=>{
p.then(
value => {
resultCount++
results[index] = value
if (resultCount === promises.length) {
resolve(results)
}
},
reason => {reject(reason)}
)
})
})
}
/*
返回一个promise对象, 此promise对象的状态是由传入的promise数组第一个返回的promise决定的
*/
Promise.race = function (promises) {
return new Promise((resolve, reject)=>{
// 遍历所有promise, 取所有的结果
promises.forEach(p=>{
// race返回的promise由第一个返回的promise来决定其race返回的promise的状态
p.then(resolve, reject)
})
})
}
// 对外暴露
window.Promise = Promise
})(window)