class CPromise {
constructor(func){
this.status = 'pedding',
this.value = null,
this.reason = null,
this.fullfilledCBS = []
this.rejectCBS = []
try {
func(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(val){
this.status = 'fulfilled'
this.value = val
this.fullfilledCBS.forEach(cb => cb(this.value))
}
reject(reason){
this.status = 'rejected'
this.reason = reason
this.rejectCBS.forEach(cb => cb(this.reason))
}
then(onFulfilled, onRejected){
let onFulfilledCB = (res,rej)=>{
return function(val){
try {
let x = onFulfilled(val)
if(x instanceof CPromise){
x.then(res,rej)
}else{
res(x)
}
} catch (error) {
rej(error)
}
}
}
let onRejectedCB = (res,rej)=>{
return function(val){
try {
let x = onRejected(val)
if(x instanceof CPromise){
x.then(res,rej)
}else{
res(x)
}
} catch (error) {
rej(error)
}
}
}
if(this.status == 'pedding'){
return new CPromise((resolve,reject)=>{
this.fullfilledCBS.push(onFulfilledCB(resolve,reject))
this.rejectCBS.push(onRejectedCB(resolve,reject))
})
}
if(this.status == 'fulfilled'){
return new CPromise((resolve,reject)=>{
onFulfilledCB(resolve,reject)(this.value)
})
}
if(this.status == 'rejected'){
return new CPromise((resolve,reject)=>{
onRejectedCB(resolve,reject)(this.value)
})
}
}
catch(cb){
return this.then(null,cb)
}
finally(cb){
return this.then(cb,cb)
}
}
new CPromise((resolve,reject)=>{
setTimeout(() => {
resolve(1)
},1000)
}).then((val)=>{
console.log('fulfilled 1 ',val)
return val
},(val)=>{
console.log('rejected 1',val)
return val
}).then((val)=>{
console.log('fullfilled 2',val)
throw 9
},(val)=>{
console.log('rejected 2',val)
}).catch(e=>{
console.log('catch',e)
return e
}).finally((val)=>{
console.log('finally',val)
return val
})
class ipromise{
constructor(fn){
this.value = null
this.status = 'pedding'
this.callback=[]
this.msg = ''
fn(this.resolve,this.reject)
}
resolve = (val)=>{
if(this.status == 'pedding'){
this.status = 'resolved'
this.value = val
if(this.callback.length){
this.then(this.callback[0].resolve)
}
}
}
reject = (msg)=>{
if(this.status == 'pedding'){
this.status = 'rejected'
this.msg = msg
if(this.callback.length){
this.then(this.callback[0].reject)
}
}
}
then(resfn,rejfn){
if(this.status =='pedding'){
this.callback.push({
resolve:resfn
,reject:rejfn})
}
if(this.status == 'resolved'){
return new ipromise((resolve,reject)=>{
const result = resfn(this.value)
if( result instanceof ipromise){
return result.then(val=>{
resolve(val)
})
}else{
resolve(result)
}
})
}
if(this.status == 'rejected'){
return new ipromise((resolve,reject)=>{
const result = rejfn(this.value)
if(result instanceof ipromise){
return result.then(val=>{
resolve(val)
})
}else{
resolve(result)
}
})
}
}
}