使用es5实现Promise方法
本篇主要讲解实现then(),catch(),Promise.resolve(),Promise.reject(),Promise.all(),Promise.race()
实现步骤
1.首先将整体结构罗列出来,包括Promise构造函数,执行器,Promise原型对象then,catch方法,函数对象resolve,reject,all,race方法
2.实现内部函数reslove,reject方法,捕获执行器异常
3.实现各种方法
新建一个Promise.js文件
(function (window) {
//三种状态
const PENDING = "pending"
const RESOLVED = "resolved"
const REJECTED = "rejected"
function Promise (excutor){//构造器
const that = this
//声明Promise状态,数据,回调方法
that.status = PENDING //给promise对象指定状态,初始值为pending
that.data = undefined //给promise对象给定一个用于存储结果数据的属性
that.callbacks = [] //用于存储回调函数{onResolved(){},onRejected(){}}
//成功执行
function resolve(value){
//判断状态是否为pending,不是则修改状态,传递数据
if(that.status !== PENDING){
return
}
that.status = RESOLVED
that.data = value
//如果有待完成的callback,立即异步执行回调onResolved
if(that.callbacks.length > 0){
setTimeout(function(){ //放入队列执行所有的成功回调
that.callbacks.forEach((callbacksObj)=>{
callbacksObj.onResolved(value)
})
})
}
}
//失败执行
function reject(reason){
if(that.status !== PENDING){
return
}
that.status = REJECTED
that.data = reason
//如果有待完成的callback,立即异步执行回调onRejected
if(that.callbacks.length > 0){
setTimeout(function(){ //放入队列执行所有的成功回调
that.callbacks.forEach((callbacksObj)=>{
callbacksObj.onRejected(reason)
})
})
}
}
// 同步执行excutor
try {
//捕获异常
excutor(resolve,reject)
} catch (error) {
reject(error)
}
}
/**Promise原型对象的then()
* 指定成功和失败的回调函数
* 返回一个新的promise对象
* 返回promise的结果由onResolved/onRejected执行结果决定
*/
Promise.prototype.then = function(onResolved,onRejected){
//最简单实现,假设当前还是pending状态
const that = this
//this.callbacks.push({onResolved,onRejected})
//要求参数是函数
onResolved = typeof onResolved === "function" ? onResolved : value => value
//异常传透关键点
onRejected = typeof onRejected === "function" ? onRejected : reason => { throw reason }
/*
执行指定的回调函数
根据执行的结果改变return的promise的状态/数据
*/
return new Promise(function(resolve,reject){
/*
封装复用函数
返回promise的结果由onResolved/onRejected执行结果决定
1. 抛出异常, 返回promise的结果为失败, reason为异常
2. 返回的是promise, 返回promise的结果就是这个结果
3. 返回的不是promise, 返回promise为成功, value就是返回值
*/
function handle(callback){
try {
const result = callback(that.data)
//判断是否为Promise实例
if(result instanceof Promise){
//返回的是promise, 返回promise的结果就是这个结果
result.then(resolve,reject)
}else{
//返回的不是promise, 返回promise为成功, value就是返回值
resolve(result)
}
} catch (error) {
//抛出异常, 返回promise的结果为失败, reason为异常
reject(error)
}
}
if(that.status === RESOLVED){
//异步执行
setTimeout(function(){
handle(onResolved)
})
}else if(that.status === REJECTED){
//异步执行
setTimeout(function(){
handle(onRejected)
})
}else {
that.callbacks.push({
onResolved(value){
handle(onResolved)
},
onRejected(reason){
handle(onRejected)
}
})
}
})
}
/**Promise原型对象的catch()
* 执行失败的回调函数
* 返回promise对象
*/
Promise.prototype.catch = function(onRejected){
const that = this
return this.then(undefined,onRejected)
}
/**Promise函数对象resolve()
* 返回指定value结果的成功promise
*/
Promise.resolve = function(value){
// 返回一个成功/失败的promise
return new Promise((resolve, reject) => {
// value是promise
if (value instanceof Promise) { // 使用value的结果作为promise的结果
value.then(resolve, reject)
} else { // value不是promise => promise变为成功, 数据是value
resolve(value)
}
})
}
/**Promise函数对象reject()
* 返回指定reason结果失败的promise
*/
Promise.reject = function(reason){
return new Promise((resolve, reject) => {
reject(reason)
})
}
/**Promise函数对象all方法
* 只有当所有promise都返回成功才会成功,否则(只要有一个失败就失败)失败
*/
Promise.all = function(promises){
//用于保存当前所有成功的数组
const values = new Array(promises.length)
//用于记录成功promise数组个数
let resolvedCount = 0
//返回新的promise
return new Promise(function(resolve,reject){
//遍历数组
promises.forEach((p,index)=>{
Promise.resolve(p).then(function(value){
//成功promise数量++
resolvedCount++
//保存成功promise返回数据
values[index] = value
//如果全部成功
if(resolvedCount === promises.length){
resolve(values)
}
},function(reason){
//只要有一个失败那就失败
reject(reason)
})
})
})
}
/**Promsie函数对象的race方法
* 其结果由第一个完成promise决定
*/
Promise.race = function(promises){
return new Promise(function(resolve,reject){
//遍历数组
promises.forEach((p)=>{
Promise.resolve(p).then(function(value){
//一旦有成功了,就返回
resolve(value)
},function(reason){
reject(reson)
})
})
})
}
/*
返回一个promise对象, 它在指定的时间后才确定结果,延时请求
*/
Promise.resolveDelay = function (value, time) {
// 返回一个成功/失败的promise
return new Promise((resolve, reject) => {
setTimeout(() => {
// value是promise
if (value instanceof Promise) { // 使用value的结果作为promise的结果
value.then(resolve, reject)
} else { // value不是promise => promise变为成功, 数据是value
resolve(value)
}
}, time)
})
}
/*
返回一个promise对象, 它在指定的时间后才失败,延时请求
*/
Promise.rejectDelay = function (reason, time) {
// 返回一个失败的promise
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(reason)
}, time)
})
}
//将Promise暴露出去
window.Promise = Promise
})(window)
实现案例:引入所写的Promise.js文件
const p = new Promise(function(resolve,reject){
setTimeout(function(){
reject(1)
},2000)
})
const p1 =Promise.resolve(2)
const p2 = Promise.resolve(3)
const p3 = Promise.resolveDelay(4,4000)
const p4 = Promise.rejectDelay(5,6000)
p.then(function(value){
console.log("请求成功",value)
},function(reason){
console.log("请求失败",reason)
})
// p.catch(function(reason){
// console.log("请求失败",reason)
// })
p1.then(function(value){
console.log("请求成功",value)
},function(reason){
console.log("请求失败",reason)
})
p2.then(function(value){
console.log("请求成功",value)
},function(reason){
console.log("请求失败",reason)
})
p3.then(function(value){
console.log("请求成功",value)
},function(reason){
console.log("请求失败",reason)
})
p4.then(function(value){
console.log("请求成功",value)
},function(reason){
console.log("请求失败",reason)
})
const pall = Promise.all([p,p1,p2])
pall.then(function(value){
console.log('all成功',value)
},function(reason){
console.log('all失败',reason)
})
const prace = Promise.race([p,p1,p2])
prace.then(function(value){
console.log('race成功',value)
},function(reason){
console.log('race失败',reason)
})
- 本文作者: étoile
- 版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!