手写Promise及其API
Promise构造函数
function Promise(executor){
this.PromiseState = 'pending'
this.PromiseResult = null
const self = this
this.callback = []
function resolve(data){
if(self.PromiseState !== 'pending') return
self.PromiseState = 'fulfilled'
self.PromiseResult = data
setTimeout(()=>{
self.callback.forEach(item => {
item.resolved(data)
});
})
}
function reject(data){
if(self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
setTimeout(()=>{
self.callback.forEach(item => {
item.rejected(data)
});
})
}
try {
executor(resolve,reject)
} catch (e) {
reject(e)
}
}
实例方法then
Promise.prototype.then = function(resolved,rejected){
const self = this
if(typeof resolved !== 'function'){
resolved =function( value ) {return value}
}
if(typeof rejected !== 'function'){
rejected = function( reason ) {throw reason}
}
return new Promise((resolve,reject)=>{
function callbackFn(type){
try {
let value = type(self.PromiseResult)
if(value instanceof Promise){
value.then(v=>{
resolve(v)
},r=>{
reject(r)
})
}else{
resolve(value)
}
} catch (e) {
reject(e)
}
}
if(this.PromiseState=='pending'){
this.callback.push({resolved:function(){callbackFn(resolved)},rejected:function(){callbackFn(rejected)}})
}
if(this.PromiseState=='fulfilled'){
setTimeout(()=>{
callbackFn(resolved)
})
}
if(this.PromiseState=='rejected'){
setTimeout(()=>{
callbackFn(rejected)
})
}
})
}
实例方法catch
Promise.prototype.catch = function(rejected){
this.then(undefined,rejected)
}
静态方法resolve
Promise.resolve = function(value){
return new Promise((resolve,reject)=>{
if(value instanceof Promise){
value.then(v=>{
resolve(v)
},r=>{
reject(r)
})
}else{
resolve(value)
}
})
}
静态方法reject
Promise.reject = function(reason){
return new Promise((resolve,reject)=>{
reject(reason)
})
}
静态方法all
Promise.all = function(PromiseArr){
let count = 0;
let arr = []
return new Promise((resolve,reject)=>{
for(let i = 0;i<PromiseArr.length;i++){
PromiseArr[i].then(v=>{
count++
arr[i] = v
if(count === PromiseArr.length){
resolve(arr)
}
},r=>{
reject(r)
})
}
})
}
静态方法race
Promise.race = function(PromiseArr){
return new Promise((resolve,reject)=>{
for(let i = 0;i<PromiseArr.length;i++){
PromiseArr[i].then(v=>{
resolve(v)
},r=>{
reject(r)
})
}
})
}
使用es6的class实现Promise
class Promise{
constructor(executor){
this.PromiseState = 'pending'
this.PromiseResult = null
const self = this
this.callback = []
function resolve(data){
if(self.PromiseState !== 'pending') return
self.PromiseState = 'fulfilled'
self.PromiseResult = data
setTimeout(()=>{
self.callback.forEach(item => {
item.resolved(data)
});
})
}
function reject(data){
if(self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
setTimeout(()=>{
self.callback.forEach(item => {
item.rejected(data)
});
})
}
try {
executor(resolve,reject)
} catch (e) {
reject(e)
}
}
then(resolved,rejected){
const self = this
if(typeof resolved !== 'function'){
resolved =function( value ) {return value}
}
if(typeof rejected !== 'function'){
rejected = function( reason ) {throw reason}
}
return new Promise((resolve,reject)=>{
function callbackFn(type){
try {
let value = type(self.PromiseResult)
if(value instanceof Promise){
value.then(v=>{
resolve(v)
},r=>{
reject(r)
})
}else{
resolve(value)
}
} catch (e) {
reject(e)
}
}
if(this.PromiseState=='pending'){
this.callback.push({resolved:function(){callbackFn(resolved)},rejected:function(){callbackFn(rejected)}})
}
if(this.PromiseState=='fulfilled'){
setTimeout(()=>{
callbackFn(resolved)
})
}
if(this.PromiseState=='rejected'){
setTimeout(()=>{
callbackFn(rejected)
})
}
})
}
catch(rejected){
this.then(undefined,rejected)
}
static resolve(value){
return new Promise((resolve,reject)=>{
if(value instanceof Promise){
value.then(v=>{
resolve(v)
},r=>{
reject(r)
})
}else{
resolve(value)
}
})
}
static reject(reason){
return new Promise((resolve,reject)=>{
reject(reason)
})
}
static all(PromiseArr){
let count = 0;
let arr = []
return new Promise((resolve,reject)=>{
for(let i = 0;i<PromiseArr.length;i++){
PromiseArr[i].then(v=>{
count++
arr[i] = v
if(count === PromiseArr.length){
resolve(arr)
}
},r=>{
reject(r)
})
}
})
}
static race(PromiseArr){
return new Promise((resolve,reject)=>{
for(let i = 0;i<PromiseArr.length;i++){
PromiseArr[i].then(v=>{
resolve(v)
},r=>{
reject(r)
})
}
})
}
}