es5的方式封装Promise
关键点:
1、时刻关注Promise的状态
2、执行的resolve和reject时候分两种情况来判别
同步执行
异步执行
3、then返回是一个Promise对象,我们要对返回值进行一个判断
4、then之后执行不管是resolve还是rejecte,都是异步代码,都要放到异步队列中执行
5、then后面默认是可以不写代码的(例如:p.then()),因此我们需要给resolve和rejecte一个默认的方法
6、catch方法可以异常穿透的
7、all和race方法都是可以直接调用的,因此需要在Promise对象上加方法,而不能在原型对象上加
8、all和race方法需要考虑部分Promise对象可能需要等待时间,但是需要返回的数组值不能乱顺序,因此需要用数组下标固定死返回值的位置
9、this的指向可能会发生问题,最好每次都保存一下this的值
function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = undefined
this.callback = []
const self = this
// 成功时候的回调方法
function resolve(data) {
setTimeout(function (){
try {
//判断状态
if (self.PromiseState !== 'pending') return;
self.PromiseResult = data
self.PromiseState = "fulfilled"
//当执行异步任务时,状态值发生了修改
self.callback.forEach(item=>{
try{
item.success(data)
} catch (e) {
reject(e)
}
})
}catch(e){
reject(e)
}
})
}
// 失败时候的回调方法
function reject(data) {
setTimeout(function() {
try{
if (self.PromiseState !== 'pending') return;
self.PromiseResult = data
self.PromiseState = "rejected"
//当执行异步任务时,状态值发生了修改
self.callback.forEach(item=>{
item.failed(data)
})
}catch (e) {
reject(e)
}
})
}
executor(resolve,reject)
}
Promise.prototype.then = function (success,failed) {
const self = this
if (typeof success !== "function") {
success = value => value
}
if (typeof failed !== "function") {
failed = (reason) => {
throw reason
}
}
// then 方法返回的结果应该是一个Promise对象
return new Promise((resolve,reject)=>{
// 封装判断逻辑
function judge(type) {
try {
let result = type(self.PromiseResult)
if (result instanceof Promise) {
if (result.PromiseState === "pending") {
self.PromiseResult = result
} else if (result.PromiseResult === "rejected") {
reject(result.PromiseResult)
} else {
resolve(result.PromiseResult)
}
} else {
resolve(result)
}
}catch (e) {
reject(e)
}
}
// 同步方法
if (this.PromiseState === 'fulfilled') {
judge(success)
}
if (this.PromiseState === 'rejected') {
judge(failed)
}
if (this.PromiseState === 'pending') {
this.callback.push({
success:function () {
judge(success)
},
failed:function () {
judge(failed)
}
})
}
})
}
Promise.prototype.catch = function (failed) {
return this.then(undefined,failed);
}
// 封装resolve
Promise.resolve = function (value) {
const self = this
if (value instanceof Promise) {
return value
} else {
return new Promise((resolve,reject)=>{
resolve(value)
})
}
}
Promise.reject = function (reason) {
return new Promise((resolve,reject)=>{
reject(reason)
})
}
Promise.all = function (arrays) {
let resultArr = []
let count = 0
return new Promise((resolve,reject)=> {
for (let i=0;i<arrays.length;i++) {
arrays[i].then(value => {
count++
resultArr[i] = value
if (count === arrays.length) {
resolve(resultArr)
}
},reason => {
reject(reason)
})
}
})
}
Promise.race = function (arrays) {
return new Promise((resolve,reject)=> {
arrays.forEach( item=> {
item.then(value => {
resolve(value)
},reason => {
reject(reason)
})
})
})
}