// promise一共三种状态,状态一旦改变就不能修改
const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REGECTED'
const resolvePromise = (x,promise2,resolve,reject) =>{
// 处理x导致的promise2是成功还是失败
// 如果x是普通值直接调用promise2和resolve
// 如果x是一个promise那么就采用x的状态,并且将结果继续调用promise2的resolve和reject向下传递
console.log(x,promise2,resolve,reject)
if(x === promise2){
return reject(new TypeError('不能自己等待自己完成,出错啦'))
}
if(typeof x === 'object' && x !== null || typeof x === 'function'){
// 有可能是一个promise
try{
let then = x.then // 因为用户返回的可能有一个then属性,一取值就报错了
if(typeof then === 'function'){ // 无法再细化了有then说明就是promise了
then.call(x,(y)=>{
resolve(y)
},(r)=>{
reject(r)
})
}else{
resolve(x) // 直接x作为成功的结果
}
}catch(e){
reject(e)
}
}else{ // 一定是一个普通得值,那么直接让这个promise变成成功态
resolve(x)
}
}
// 定义promise类
class MyPromise{
constructor(executor){
this.value= undefined // value成功的值
this.reason = undefined // reason失败的原因
this.status = PENDING // 当前promise的状态
this.onResolvedCallbacks = [] // 待执行的回调列表
this.onRejectedCallbacks = [] // 待执行的失败列表
const resolve = (value) =>{ // 成功就修改状态执行列表
if(this.status == PENDING){
this.value = value
this.status = FULFILLED
this.onResolvedCallbacks.forEach(callback => callback(value))
}
}
const reject = (reason) =>{ // 失败修改状态执行列表
if(this.status == PENDING){
this.reason = reason
this.status = REJECTED
this.onRejectedCallbacks.forEach(callback => callback(reason))
}
}
try{
executor(resolve,reject) // 执行回调
}catch(e){ // 如果执行时发生了异常就将异常作为失败的原因
reject(e)
}
}
then(onFulfilled,onRejected){
// 链式调用的核心 就是处理x 和promise之间的关系
let promise2 = new Promise((resolve,reject) =>{
if(this.status == FULFILLED){
// 用定时器为啦promise可以出来
setTimeout(()=>{
try{
let x = onFulfilled(this.value)
resolvePromise((x,promise2,resolve,reject))
}catch(e){
reject(e)
}
},0)
}
if(this.status == REJECTED){
setTimeout(()=>{
try{
let x = onRejected(this.reason)
resolvePromise((x,promise2,resolve,reject))
}catch(e){
reject(e)
}
},0)
}
if(this.status == PENDING){
// 这时用户没有调用成功或者失败 没有reject和resolve
this.onResolvedCallbacks.push(()=>{
setTimeout(()=>{
try{
let x = onFulfilled(this.value)
resolvePromise((x,promise2,resolve,reject))
}catch(e){
reject(e)
}
},0)
})
this.onRejectedCallbacks.push(()=>{
setTimeout(()=>{
try{
let x = onRejected(this.reason)
resolvePromise((x,promise2,resolve,reject))
}catch(e){
reject(e)
}
},0)
})
}
})
return promise2
}
}
// 实例方法
MyPromise.prototype.catch = function(reject){
return this.then(null,reject)
}
MyPromise.prototype.finally = function(cb){
return this.then((value)=>{
return MyPromise.resolve(cb()).then(()=>{
return value
})
},(err)=>{
return MyPromise.resolve(cb()).then(()=>{
throw err
})
})
}
// 静态方法 all allSettled race any resolve reject
MyPromise.prototype.all = function(list){
let len = list.length
let result = []
let count = 0
return new Promise((resolve,reject)=>{
for(let p of list){
Promise.resolve(p).then(res =>{
result[count] = res
count++
if(count === len){
resolve(result)
}
}).catch(e => {
reject(e)
})
}
})
}
MyPromise.prototype.allSettled = function(list){
let len = list.length
let result = []
let count = 0
return new Promise((resolve,reject)=>{
for(let p of list){
Promise.resolve(p).then(res =>{
result[count] = {
status: 'fulfiled',
value: res
}
count++
if(count === len){
resolve(result)
}
}).catch(e => {
result[count] = {
status: 'rejected',
value: e
}
count++
if(count === len){
reject(result)
}
})
}
})
}
MyPromise.prototype.any = function(list){
let len = list.length
let result = []
let count = 0
return new Promise((resolve,reject)=>{
for(let p of list){
Promise.resolve(p).then(res =>{
resolve(res)
}).catch(e => {
result[count]= e;
count++
if(count === len){
reject(result)
}
})
}
})
}
MyPromise.prototype.race = function(list){
let len = list.length
let result = []
let count = 0
return new Promise((resolve,reject)=>{
for(let p of list){
MyPromise.resolve(p).then((value)=>{
resolve(value)
},(err)=>{
reject(err)
})
}
})
}
js-手写promise
于 2022-06-10 14:08:11 首次发布