一,整体结构
采用es5的语法来写:
(function(window
){
function Promise(excutor
){
}
Promise
.prototype
.then=function (onResolved
,onRejected
){
}
Promise
.prototype
.catch=function (onRejected
){
}
Promise
.resolve=function(value
){
}
Promise
.reject=function(reason
){
}
Promise
.all=function(promises
){
}
Promise
.race=function(promises
){
}
window
.Promise
=Promise
})(window
)
二,构造函数Promise的实现
第一步:因为excutor是立即同步执行的,所以在promise函数内部需要调用这个excutor函数,并且参数是resolve和reject这两个回调函数。 第二步:因为参数是这两个回调函数,所以这两个回调函数就需要事先定义好。 第三步:根据平时对promise的使用,可以知道,promise必然有个状态属性(peding,resolve,reject),还有一个用于存储结果的属性,还有一个存储回调函数的数组:
(function(window
){
function Promise(excutor
){
const that
=this
that
.status
='pending'
that
.data
=undefined
that
.callbacks
=[]
function resolve(value
){
if(that
.status
!=='pending'){return}
that
.status
='resolved'
that
.data
=value
if(that
.callbacks
.length
>0){
setTimeout(()=>{
that
.callbacks
.forEach(callbacksObj
=>{
callbacksObj
.onResolved(value
)
})
})
}
}
function reject(reason
){
if(that
.status
!=='pending'){return}
that
.status
='rejected'
that
.data
=reason
if(that
.callbacks
.length
>0){
setTimeout(()=>{
that
.callbacks
.forEach(callbacksObj
=>{
callbacksObj
.onRejected(reason
)
})
})
}
}
try{
excutor(resolve
,reject
)
}catch(error
){
reject(error
)
}
}
Promise
.prototype
.then=function (onResolved
,onRejected
){
this.callbacks
.push({
onResolved
,
onRejected
})
}
Promise
.prototype
.catch=function (onRejected
){
}
Promise
.resolve=function(value
){
}
Promise
.reject=function(reason
){
}
Promise
.all=function(promises
){
}
Promise
.race=function(promises
){
}
window
.Promise
=Promise
})(window
)
也就是说:这部分是excutor实参, 而在promise构造函数内部,第一个执行的就是这个实参函数: 而这里面调用了resolve(1),这个1类比于异步操作的结果 于是就去执行resolve函数,也就是说resolve是定义者定义在promise中,使用者在外面异步操作完成后调用。 而resolve里还要调用.then中的函数: 简单写: 这样就是先指定两个回调函数,等resolve调用时,就可以直接在callbacks里面找到并使用了。
三,then方法的实现
(function(window
){
const PENDING='pending'
const RESOLVED='resolved'
const REJECTED='rejected'
function Promise(excutor
){
const that
=this
that
.status
=PENDING
that
.data
=undefined
that
.callbacks
=[]
function resolve(value
){
if(that
.status
!==PENDING){return}
that
.status
=RESOLVED
that
.data
=value
if(that
.callbacks
.length
>0){
setTimeout(()=>{
that
.callbacks
.forEach(callbacksObj
=>{
callbacksObj
.onResolved(value
)
})
})
}
}
function reject(reason
){
if(that
.status
!==PENDING){return}
that
.status
=REJECTED
that
.data
=reason
if(that
.callbacks
.length
>0){
setTimeout(()=>{
that
.callbacks
.forEach(callbacksObj
=>{
callbacksObj
.onRejected(reason
)
})
})
}
}
try{
excutor(resolve
,reject
)
}catch(error
){
reject(error
)
}
}
Promise
.prototype
.then=function (onResolved
,onRejected
){
onResolved
=typeof onResolved
=== 'function' ? onResolved
: value
=>value
onRejected
=typeof onRejected
=== 'function' ? onRejected
: reason
=>{throw reason
}
const that
=this
return new Promise((resolve
,reject
)=>{
function handle(callback
){
try{
const result
=callback(that
.data
)
if(result
instanceof Promise){
result
.then(
value
=>resolve(value
),
reason
=>reject(reason
)
)
}else{
resolve(result
)
}
}catch(error
){
reject(error
)
}
}
if(that
.status
===PENDING){
this.callbacks
.push({
onResolved(value
){
handle(onResolved
)
},
onRejected(reason
){
handle(onRejected
)
}
})
}else if(that
.status
===RESOLVED){
setTimeout(()=>{
handle(onResolved
)
})
}else{
setTimeout(()=>{
handle(onRejected
)
})
}
})
}
Promise
.prototype
.catch=function (onRejected
){
return this.then(undefined
,onRejected
)
}
Promise
.resolve=function(value
){
}
Promise
.reject=function(reason
){
}
Promise
.all=function(promises
){
}
Promise
.race=function(promises
){
}
window
.Promise
=Promise
})(window
)
四,Promise.resolve和reject的实现
Promise
.resolve=function(value
){
return new Promise((resolve
,reject
)=>{
if(value
instanceof Promise){
value
.then(
value
=>resolve(value
),
reason
=>reject(reason
)
)
}else{
resolve(value
)
}
})
}
Promise
.reject=function(reason
){
return new Promise((resolve
,reject
)=>{
reject(reason
)
})
}
五,Promise.all方法
Promise
.all=function(promises
){
const values
=new Array(promises
.length
)
let acount
=0
return new Promise((resolve
,reject
)=>{
promises
.forEach((p
,index
)=>{
p
.then(
value
=>{
values
[index
]=value
acount
++
if(acount
===promises
.length
){
resolve(values
)
}
},
reason
=>{
reject(reason
)
}
)
})
})
}
六,Promise.race方法
Promise
.race=function(promises
){
return new Promise((resolve
,reject
)=>{
promises
.forEach((p
,index
)=>{
p
.then(
value
=>{
resolve(value
)
},
reason
=>{
reject(reason
)
}
)
})
})
七,整体的promise
(function(window
){
const PENDING='pending'
const RESOLVED='resolved'
const REJECTED='rejected'
function Promise(excutor
){
const that
=this
that
.status
=PENDING
that
.data
=undefined
that
.callbacks
=[]
function resolve(value
){
if(that
.status
!==PENDING){return}
that
.status
=RESOLVED
that
.data
=value
if(that
.callbacks
.length
>0){
setTimeout(()=>{
that
.callbacks
.forEach(callbacksObj
=>{
callbacksObj
.onResolved(value
)
})
})
}
}
function reject(reason
){
if(that
.status
!==PENDING){return}
that
.status
=REJECTED
that
.data
=reason
if(that
.callbacks
.length
>0){
setTimeout(()=>{
that
.callbacks
.forEach(callbacksObj
=>{
callbacksObj
.onRejected(reason
)
})
})
}
}
try{
excutor(resolve
,reject
)
}catch(error
){
reject(error
)
}
}
Promise
.prototype
.then=function (onResolved
,onRejected
){
onResolved
=typeof onResolved
=== 'function' ? onResolved
: value
=>value
onRejected
=typeof onRejected
=== 'function' ? onRejected
: reason
=>{throw reason
}
const that
=this
return new Promise((resolve
,reject
)=>{
function handle(callback
){
try{
const result
=callback(that
.data
)
if(result
instanceof Promise){
result
.then(
value
=>resolve(value
),
reason
=>reject(reason
)
)
}else{
resolve(result
)
}
}catch(error
){
reject(error
)
}
}
if(that
.status
===PENDING){
this.callbacks
.push({
onResolved(value
){
handle(onResolved
)
},
onRejected(reason
){
handle(onRejected
)
}
})
}else if(that
.status
===RESOLVED){
setTimeout(()=>{
handle(onResolved
)
})
}else{
setTimeout(()=>{
handle(onRejected
)
})
}
})
}
Promise
.prototype
.catch=function (onRejected
){
return this.then(undefined
,onRejected
)
}
Promise
.resolve=function(value
){
return new Promise((resolve
,reject
)=>{
if(value
instanceof Promise){
value
.then(
value
=>resolve(value
),
reason
=>reject(reason
)
)
}else{
resolve(value
)
}
})
}
Promise
.reject=function(reason
){
return new Promise((resolve
,reject
)=>{
reject(reason
)
})
}
Promise
.all=function(promises
){
const values
=new Array(promises
.length
)
let acount
=0
return new Promise((resolve
,reject
)=>{
promises
.forEach((p
,index
)=>{
p
.then(
value
=>{
values
[index
]=value
acount
++
if(acount
===promises
.length
){
resolve(values
)
}
},
reason
=>{
reject(reason
)
}
)
})
})
}
Promise
.race=function(promises
){
return new Promise((resolve
,reject
)=>{
promises
.forEach((p
,index
)=>{
p
.then(
value
=>{
resolve(value
)
},
reason
=>{
reject(reason
)
}
)
})
})
}
window
.Promise
=Promise
})(window
)