手写实现Promise
1.Promise构造函数
promise构造函数,参数为一个执行器,执行器函数有两个参数成功/失败的回调
调用成功/失败的回调的前提条件就是状态为pending状态当不为pending状态时调用无效
//实现promise构造函数
function Promise(excutor)
{
//将this进行存放,因为在实现resolve函数时他是外部进行直接调用this指向window
let self = this
self.state = "pending"
self.data = undefined
//用于先指定回调函数的情况将回调函数以{onResolved.onRejected}
self.callbacks = []
//定义两个修改状态的函数
function resolve(value)
{
//当前状态不是pending的时候修改状态
if(self.state !== "pending") return
self.state = "resolved"
self.data = value
//如果存放回调函数的数组里有内容就异步调用执行
if(self.callbacks.length >0)
{
setTimeout(()=>{
self.callbacks.filter(cbsObj => {
cbsObj.onResolved(value)
})
})
}
}
function reject(reason)
{
if(self.state !== "pending") return
self.state = "rejected"
self.data = reason
//如果存放回调函数的数组里有内容就异步调用执行
if(self.callbacks.length >0)
{
setTimeout(()=>{
self.callbacks.filter(cbsObj => {
cbsObj.onRejected(reason)
})
})
}
}
//调用执行器函数,如果抛出异常则直接调用reject
try{
excutor(resolve,reject)
}catch (error) {
reject(error)
}
}
//then方法,两个参数成功的回调和失败的回调
Promise.prototype.then = function(onResolved,onRejected)
{
//先简单实现then方法
this.callbacks.push({onResolved,onRejected})
}
直接使用即可
let p = new Promise((resolve, reject) => {
//目前我们实现的只能先指定回调函数
setTimeout(()=>{
// resolve(12)
reject(12)
},100)
})
p.then(value => {
console.log("onResolved1 "+value)
},reason => {
console.log("onRejected1 "+reason)
})
p.then(value => {
console.log("onResolved2 "+value)
},reason => {
console.log("onRejected2 "+reason)
})
2.Promise实例的then方法
then函数,有两个参数分别是成功时的回调和失败时的回调,在resolved/rejected状态下会直接执行相应状态的回调函数。在pending状态时,会存放下回调
返回一个新的promise对象,promise对象的结果由三种情况即:
1.当返回的是一个非promise对象的值是,会成功,成功的值是指定的值
2.返回的是promise的对象,那么返回的就是该promise
3.js抛出异常,那么返回失败的promise,reason是error
Promise.prototype.then = function (onResolved,onRejected)
{
let self = this
//设置默认值处理异常穿透的问题
onResolved = typeof onResolved == "function" ? onResolved : value => value
onRejected = typeof onRejected == "function" ? onRejected : reason => {throw reason}
return new Promise((resolve,reject)=>{
//影响返回新promise状态的三种情况
function handle(callback)
{
try{
let result = callback(self.state)
if(result instanceof Promise)
{
resolve.then(
value => {
resolve(value)
},
reason =>{
reject(reason)
}
)
}else
{
resolve(result)
}
}catch (e) {
reject(e)
}
}
if(self.state === "pending")
{
self.callbacks.push({
onResolved(){
handle(onResolved)
},
onRejected() {
handle(onRejected)
}
})
}else if(self.state === "resolved")
{
handle(onResolved)
}else
{
handle(onRejected)
}
})
}
测试
let p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(12)
},100)
}).then(value => {console.log(value)}).then(value => {console.log(value)})
3.Promise实例的catch方法
catch返回一个promise,并且该函数只指定失败的回调
Promise.prototype.catch = function (onRejected)
{
return this.then(undefined,onRejected)
}
4.Promise的resolve方法
Promise.resolve函数,一个参数,可以传递一个非promise的值和一个promise
非promise的值,那么就返回一个成功promise value是该值
传递promise,那么返回的就是该promise的状态和值
Promise.resolve = function (value)
{
return new Promise((resolve,reject)=>{
//判断参数是否为promise
if(value instanceof Promise)
{
value.then(
value1 => {resolve(value1)},
reason => {reject(reason)}
)
}else
{
resolve(value)
}
})
}
5.Promise的reject方法
Promise.reject返回一个失败的promise reason值为传进来的那个值
Promise.reject = function (reason)
{
return new Promise((resolve,reject)=>{
reject(reason)
})
}
测试
let p = Promise.resolve(Promise.resolve(1))
let p1 = Promise.resolve(2)
let p2 = Promise.resolve(Promise.reject(3))
p.then(value => console.log(value))
p1.then(value => console.log(value))
p2.catch(reason => console.log(reason))
6.Promise的all方法
Promise.all 该方法接收一个数组类型的参数,
返回一个新的promise的状态当数组内promise全部成功时成功有一个失败就失败
也可以传递非promise的值,当做Promise.resolve(value)处理
Promise.all = function (promises)
{
//计数器用来计数成功promise
let resolveCount = 0
//用来存放成功promise结果的数组
let values = new Array(promises.length)
return new Promise((resolve,reject)=>{
promises.filter((p,index)=>{
Promise.resolve(p).then(
value=>{
resolveCount++
values[index] = value
if(resolveCount === promises.length)
{
resolve(values)
}
},
reason=>{
reject(reason)
}
)
})
})
}
7.Promise的race方法
Promise.race 该方法返回的promise按第一个执行完毕的算
Promise.race = function (promises)
{
return new Promise((resolve,reject)=>{
promises.filter(p=>{
Promise.resolve(p).then(
value => {
resolve(value)
},
reason => {
reject(reason)
}
)
})
})
}
8.完整代码
(function(w){
function Promise(excuort)
{
let self = this
self.state = "pending"
self.data = undefined
//存放一个对象{onResolved,onRejected}
self.callbacks = []
function resolve(value)
{
if(self.state !== "pending") return
self.state = "resolved"
self.data = value
if(self.callbacks.length >0)
{
setTimeout(()=>{
self.callbacks.filter(p =>{
p.onResolved(self.data)
})
})
}
}
function reject(reason)
{
if(self.state !== "pending") return
self.state = "rejected"
self.data = value
if(self.callbacks.length >0)
{
setTimeout(()=>{
self.callbacks.filter(p =>{
p.onRejected(self.data)
})
})
}
}
try{
excuort(resolve,reject)
}catch (error) {
reject(error)
}
}
Promise.prototype.then = function (onResolved,onRejected)
{
let self = this
//设置默认值处理异常穿透的问题
onResolved = typeof onResolved == "function" ? onResolved : value => value
onRejected = typeof onRejected == "function" ? onRejected : reason => {throw reason}
return new Promise((resolve,reject)=>{
function handle(callback)
{
try{
let result = callback(self.state)
if(result instanceof Promise)
{
resolve.then(
value => {
resolve(value)
},
reason =>{
reject(reason)
}
)
}else
{
resolve(result)
}
}catch (e) {
reject(e)
}
}
if(self.state === "pending")
{
self.callbacks.push({
onResolved(){
handle(onResolved)
},
onRejected() {
handle(onRejected)
}
})
}else if(self.state === "resolved")
{
handle(onResolved)
}else
{
handle(onRejected)
}
})
}
Promise.prototype.catch = function (onRejected)
{
this.then(undefined,onRejected)
}
Promise.resolve = function (value)
{
return new Promise((resolve,reject)=>{
if(value instanceof Promise)
{
value.then(
value1 => {resolve(value1)},
reason => {reject(reason)}
)
}else
{
resolve(value)
}
})
}
Promise.reject = function (reason)
{
return new Promise((resolve,reject)=>{
reject(reason)
})
}
Promise.all = function (promises)
{
let resolveCount = 0
let values = new Array(promises.length)
return new Promise((resolve,reject)=>{
promises.filter((p,index)=>{
Promise.resolve(p).then(
value=>{
resolveCount++
values[index] = value
if(resolveCount === promises.length)
{
resolve(values)
}
},
reason=>{
reject(reason)
}
)
})
})
}
Promise.race = function (promises)
{
return new Promise((resolve,reject)=>{
promises.filter(p=>{
Promise.resolve(p).then(
value => {
resolve(value)
},
reason => {
reject(reason)
}
)
})
})
}
})(window)