手写Promise
function myPromise(excutor){
let self = this
self.status = 'pending'
self.value = null
self.reason = null
self.onfulfilledCallback = []
self.onrejectedCallback = []
function resolve(value){
if(self.status == 'pending'){
self.status = 'onfulfilled'
self.value = value
self.onfulfilledCallback.forEach(item=>{
item(value)
})
}
}
function reject(reason){
if(self.status == 'pending'){
self.status = 'onrejected'
self.reason = reason
self.onrejectedCallback.forEach(item=>{
item(reason)
})
}
}
try{
excutor(resolve,reject)
}catch(err){
reject(err)
}
}
myPromise.prototype.then = function(onFulfilled,onRejected){
let self = this
onFulfilled = typeof onFulfilled == 'function'?onFulfilled:function(data){resolve(data)}
onRejected = typeof onRejected == 'function'?onRejected:function(err){throw err}
if(self.status == 'onfulfilled'){
return new myPromise((resolve,reject)=>{
try{
let x = onFulfilled(self.value)
x instanceof myPromise?x.then(resolve,reject):resolve(x)
}catch(err){
reject(err)
}
})
}
if(self.status == 'onrejected'){
return new myPromise((resolve,reject)=>{
try{
let x = onRejected(self.reason)
x instanceof myPromise?x.then(resolve,reject):resolve(x)
}catch(err){
reject(err)
}
})
}
if(self.status == 'pending'){
return new myPromise((resolve,reject)=>{
self.onfulfilledCallback.push(function(){
let x = onFulfilled(self.value)
x instanceof myPromise?x.then(resolve,reject):resolve(x)
})
self.onrejectedCallback.push(function(){
let x = onRejected(self.reason)
x instanceof myPromise?x.then(resolve,reject):resolve(x)
})
})
}
}
myPromise.prototype.catch = function (fn){
return this.then(null,fn)
}
myPromise.prototype.finally = function (resolvefn,rejectfn){
return this.then(resolvefn,rejectfn)
}
let p = new myPromise((resolve,reject)=>{
resolve('p')
})
p.then(data=>{
console.log('resolve',data) // resolve p
}).catch(err=>{
console.log('reject',err)
})
手写Promise.all()
const p = Promise.all([p1, p2, p3]);
Promise.all()方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。另外,Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。
p的状态由p1、p2、p3决定,分成两种情况。
(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
myPromise.myAll = function(promiseArr){
return new myPromise((resolve,reject)=>{
let count = 0
let arr = []
for(var i=0;i<promiseArr.length;i++){
promiseArr[i].then(v=>{
count ++
arr[i] = v
if(count == promiseArr.length){
resolve(arr)
}
},err=>{
reject(err)
})
}
})
}
let p = new myPromise((resolve,reject)=>{
resolve('p')
})
let p1 = new myPromise((resolve,reject)=>{
reject('p1')
})
let p2 = new myPromise((resolve,reject)=>{
reject('p2')
})
myPromise.myAll([p,p1,p2]).then(value=>{
console.log('all--resolve',value)
}).catch(err=>{
console.log('all--reject',err) //all--reject p1
})
手写Promise.race()
const p = Promise.race([p1, p2, p3]);
只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
myPromise.myRace = function(promiseArr){
return new myPromise((resolve,reject)=>{
for(var i =0;i<promiseArr.length;i++){
promiseArr[i].then(value=>{
resolve(value)
},err=>{
reject(err)
})
}
})
}
let p = new myPromise((resolve,reject)=>{
resolve('p')
})
let p1 = new myPromise((resolve,reject)=>{
reject('p1')
})
let p2 = new myPromise((resolve,reject)=>{
reject('p2')
})
myPromise.myRace([p2,p,p1]).then(value=>{
console.log('race--resolve',value)
}).catch(err=>{
console.log('race--reject',err) //race--reject p2
})
手写Promise.allSettled()
const p = Promise.allSettled([p1, p2, p3]);
Promise.allSettled()方法接受一个数组作为参数,数组的每个成员都是一个 Promise 对象,并返回一个新的 Promise 对象。只有等到参数数组的所有 Promise 对象都发生状态变更(不管是fulfilled还是rejected),返回的 Promise 对象才会发生状态变更。
myPromise.myAllSettled = function(promiseArr){
return new myPromise((resolve,reject)=>{
let count = 0
let arr = []
for(var i=0;i<promiseArr.length;i++){
promiseArr[i].finally(v=>{
count ++
arr[i] = {status:'fulfilled',value:v}
if(count == promiseArr.length){
resolve(arr)
}
},err=>{
count ++
arr[i] = {status:'rejected',reason:err}
if(count == promiseArr.length){
resolve(arr)
}
}
)
}
})
}
let p = new myPromise((resolve,reject)=>{
resolve('p')
})
let p1 = new myPromise((resolve,reject)=>{
reject('p1')
})
let p2 = new myPromise((resolve,reject)=>{
reject('p2')
})
myPromise.myAllSettled([p,p1,p2]).then(value=>{
console.log('allSettled--resolve',value)
}).catch(err=>{
console.log('allSettled--reject',err)
})
//allSettled--resolve
(3) [{…}, {…}, {…}]
0: {status: 'fulfilled', value: 'p'}
1: {status: 'rejected', reason: 'p1'}
2: {status: 'rejected', reason: 'p2'}
length: 3[[Prototype]]: Array(0)
手写Promise.any()
const p = Promise.any([p1, p2, p3]);
只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态
myPromise.myAny = function(promiseArr){
return new myPromise((resolve,reject)=>{
let count = 0
let arr = []
for(var i=0;i<promiseArr.length;i++){
promiseArr[i].then(v=>{
resolve(v)
},err=>{
count ++
arr[i] = err
if(count == promiseArr.length){
reject(arr)
}
})
}
})
}
let p = new myPromise((resolve,reject)=>{
resolve('p')
})
let p1 = new myPromise((resolve,reject)=>{
reject('p1')
})
let p2 = new myPromise((resolve,reject)=>{
reject('p2')
})
myPromise.myAny([p,p1,p2]).then(value=>{
console.log('any--resolve',value) //any--resolve p
}).catch(err=>{
console.log('any--reject',err)
})