Promise的基本使用,手写一个Promise

Promise之前,异步请求的处理方式

使用回调函数的方式的弊端:

1. 如果是我们自己封装的requestData,那么我们在封装的时候必须要自己设计好callback名称,并且使用好

2. 如果我们使用的是别人封装的requestData或者一些第三方库,那么我们必须去看别人的源码或者文档,才知道它这个函数需要怎么去获取到结果

// 以前解决异步请求的处理方式
function requestData(url, successCallback, failtureCallback) {
  // 模拟网络请求
  setTimeout(() => {
    // 拿到请求结果
    if(url === 'coder') {
      // url是coder请求成功
      const names = ['abc','cba','nba']
      successCallback(names)
    }else {
      // 否则失败
      const errMessage = '请求失败,url错误'
      failtureCallback(errMessage)
    }
  }, 3000)
}


requestData('coder',(res) => {
  console.log(res);
},err => {
  console.log(err);
})

Promise的基本使用

在通过new创建Promise对象时,我们需要传入一个回调函数,我们称之为executor

这个回调函数会被立即执行,并且给传入另外两个回调函数resolve,reject

当我们调用resolve回调函数时,会执行Promise对象的then方法传入的回调函数

当我们调用reject回调函数时,会执行Promise对象的catch方法传入的回调函数

function foo() {
  return new Promise((resolve,reject) => {
    resolve()
    reject()
  })
}

// main.js
const fooPromise = foo()

// then方法传入的两个回调函数,
// 第一个回调函数,会在Promise执行resulve函数时,被回调
// 第二个回调函数,会在Promise执行reject函数时,被回调
fooPromise.then((res) => {
  console.log(res);
}, (err) => {
  console.log(err);
})

class Person {
  constructor(callback) {
    let foo = function(){}
    let bar = function(){}

    callback(foo, bar)
  }
}

const p = new Person((boo,bar) => {
  boo()
  bar()
})

// 传入的这个函数,称之为executor
// > resolve: 回调函数, 在成功时,调用resolve函数
// > reject: 回调函数, 在失败时,回调reject函数

const promise = new Promise((resolve, reject) => {
  console.log('Promise传入的函数被立即执行了');

  resolve() // 成功
  reject() // 失败
})

promise.then()

异步请求的Promise

// 以前解决异步请求的处理方式
function requestData(url) {

  return new Promise((resolve,reject) => {
  // 模拟网络请求
  setTimeout(() => {
    // 拿到请求结果
    if(url === 'coder') {
      // url是coder请求成功
      const names = ['abc','cba','nba']
      resolve(names)
    }else {
      // 否则失败
      const errMessage = '请求失败,url错误'
      reject(errMessage)
    }
  }, 3000)
  })
}


const promise = requestData('coder')

promise.then((res) => {
  console.log('请求成功:',res);
}, (err) => {
  console.log('请求失败:',err);
})

Promise的三种状态

Promise使用过程,我们可以将它划分成三个状态

注意: 状态一旦确定下来,那么就是不可更改的

1. 待定(pending): 初始状态,既没有被兑现,也没有被拒绝, 当执行executor中的代码时,处于该状态

2. 已兑现(fulfilled, resolved): 意味着操作成功完成, 执行resolve时,处于该状态

3. 已拒绝(rejected): 意味着操作失败; 执行reject时,处于该状态

const promise = new Promise((resolve,reject) => {

})

promise.then(res => {}, err=> {})

// 完全等价于下面的代码

// Promise使用过程,我们可以将它划分成三个状态
/**
 * 1. 待定(pending): 初始状态,既没有被兑现,也没有被拒绝, 当执行executor中的代码时,处于该状态
 * 2. 已兑现(fulfilled, resolved): 意味着操作成功完成, 执行resolve时,处于该状态
 * 3. 已拒绝(rejected): 意味着操作失败; 执行reject时,处于该状态
 * 4. 注意: 状态一旦确定下来,那么就是不可更改的
 * **/
new Promise((resolve, reject) => {
  // pending状态
  console.log('--------');
  resolve() // 处于fulfilled状态
  // reject() // 处于reject状态
}).then(res => {
  console.log('res:',res);
}, err => {
  console.log('err:',err);
})

Promise的resolve参数

/**
 * resolve参数
 * 1. 传入普通的值,或者对象 pending -> fulfilled
 * 2. 传入一个Promise
 *      那么当前的Promise的状态会由传入的Promise来决定
 *      相当于进行了移交
 * 3. 传入一个对象,并且这个对象有一个then方法(并且这个对象是实现了thenable接口)
 *     那么也会执行该then方法,并且由该then方法决定后续状态
 * **/


// 2.传入Promise的特殊情况
const newPromise = new Promise((resolve,reject) => {
  // resolve('aaaaa')
  reject('err message')
})

new Promise((resolve,reject) => {
  // resolve() // 第一种
  resolve(newPromise) // 第二种
}).then(res => {
  console.log('res:', res);
},err => {
  console.log('err:', err);
})


// 3. 传入一个对象,这个兑现由then方法
new Promise((resolve,reject) => {
  // pending -> fulfilled
  const obj = {
    then: function(resolve,reject) {
      // resolve('resulve message')
      reject('reject message')
    }
  }
  resolve(obj)
}).then(res => {
  console.log('res:', res);
},err => {
  console.log('err:', err);
})

Promise对象的then方法

Promise对象上的方法,是在Promise.prototype上的方法

// Promise 有那些对象方法
// console.log(Object.getOwnPropertyDescriptors(Promise.prototype));

const promise = new Promise((resolve,reject) => {
  resolve('hahaha')
})

// 1. 同一个promise可以被多次调用then方法
// 当我们的resolve方法被回调时,所有的then方法传入的回调都会被调用
promise.then(res => {
  console.log('被调用的第一个',res);
})

promise.then(res => {
  console.log('被调用的第二个',res);

})

promise.then(res => {
  console.log('被调用的第三个',res);

})


// 2.then方法传入的 ”回调函数: 可以有返回值“
// then方法本身也是有一个返回值, 它的返回值是Promise
//  1. > 如果我们返回的是一个普通值,那么这个普通的值被作为一个新的Promise的resolve值
promise.then(res => {
  return 11111
  // 上面的操作,在内部其实做的是下面的操作
  // return new Promise(resolve => resolve(11111))
}).then(res => {
  // 这里获取到的值,是上面then返回的值
  console.log('res:', res); // 11111
})


//  2. > 如果我们返回的是一个Promise
promise.then(res => {
  return new Promise((resolve,reject) => {
    setTimeout(() => {
      resolve(11111)
    },3000)
  })
}).then(res => {
  console.log('res:', res); // res: 11111
})

// 3. > 如果我们返回的是一个对象,并且该对象实现了thenable
promise.then(res => {
  return {
    then: function(resolve,reject) {
      resolve(22222)
    }
  }
}).then(res => {
  console.log('res:', res); // res: 22222
})

Promise对象的catch方法

const promise = new Promise((resolve,reject) => {
  // reject('rejected status')
  throw new Error('rejected status') 
})

// 1. 当executor抛出异常时,也会调用错误(拒绝)捕获的回调函数的
promise.then(undefined, err => {
  console.log('err:',err);
})

// 2.通过catch方法来传入错误(拒绝)捕获的回调函数
// 这种写法是不符合 promise/ a+规范
promise.catch(err => [
  console.log('err:', err)
])

// 第三种写法
promise.then(res => {
  return new Promise(reject => {
    reject('then rejected status')
  })
}).catch(err=> {
  // 这里的catch 最先捕获的是最外层抛出的异常
  console.log('err:', err);
})


// 拒绝捕获的问题
const promise = new Promise((resolve,reject) => {
  reject('1111')
})


// 此是这里会直接报错,因为这时的这两个函数想当于独立调用,第一个函数,没有写接收异常的处理函数
promise.then(res => {
  console.log(res);
})

promise.catch(err => {
  console.log(err);
})


// catch方法的返回值
const promise = new Promise((resolve,reject)=> {
  reject('11111')
})

promise.then(res => {
  console.log('res:',res);
}).catch(err => {
  return 'catch return value' // 这里的返回值跟then里是一样的,都是通过resolve返回一个promise
}).then(res => {
  console.log('res result:', res);
}).catch(err => {
  console.log('err result:', err);
})

Promise对象的finally方法

const promise = new Promise((resolve, reject) => {
  resolve('resolve message')
})

promise.then(res => {
  console.log('res:', res);
}).catch(err=> {
  console.log('err:',err);
}).finally(() => { 
  // 这里的代码是一定会执行的
  console.log('finally code execute');
})

Promise类的resolve方法

// 类方法Promise.resolve
const promise = Promise.resolve({name: 'coder'})

// 相当于
const promise2 = new Promise(resolve=> resolve({name: 'coder'}))


// 2.传入Promise
const promise3 = Promise.resolve(new Promise(resolve => resolve('123456789')))

promise3.then(res => {
  console.log('res:',res); // 123456789
})

// 3.传入thenable对象
const obj = {
  then: function(resolve) {
    resolve('123456789')
  }
}
const promise4 = Promise.resolve(new Promise(resolve => resolve(obj)))

promise3.then(res => {
  console.log('res:',res); // 123456789
})

Promise类的reject方法

const promise = Promise.reject('rejected message')
// 相当于
const promise2 = new Promise(reject => reject('rejected message'))

// 注意: 无论传入什么值都是一样的
const promise3 = Promise.reject(new Promise(resolve => resolve('12345678')))

promise3.then(res => {
  console.log("res:",res);
}).catch(err=> {
  console.log('err:',err); // err: Promise { '12345678' }
})

Promise类的all方法

// 创建多个Promise
const p1 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve(111)
  },1000)
})

const p2 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve(222)
  },2000)
})

const p3 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve(333)
  },3000)
})

// 所有的Promise都变成fulfilled时,再拿到结果
// 意外: 在拿到所有结果之前,有一个promise变成了rejected,那么整个promise是rejected

Promise.all([p2, p1,p3,'aaaa']).then(res => {
  console.log(res); // [ 222, 111, 333, 'aaaa' ]
}).catch(err => {
  console.log('err:',err);
})

Promise类的allSettled方法

// 创建多个Promise
const p1 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve(111)
  },1000)
})

const p2 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve(222)
  },2000)
})

const p3 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve(333)
  },3000)
})

// allSettled 会等所有的都有结果后返回所有的结果
Promise.allSettled([p2,p1,p3]).then(res => {
  console.log(res);
  /**
   * [
      { status: 'fulfilled', value: 222 },
      { status: 'fulfilled', value: 111 },
      { status: 'fulfilled', value: 333 }
     ]
   * **/

}).catch(err => {
  console.log('err:',err);
})

Promise类的case方法

// 创建多个Promise
const p1 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve(111)
  },1000)
})

const p2 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve(222)
  },2000)
})

const p3 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve(333)
  },3000)
})

// race 竞技/竞赛
// 当几个promise有一个resovled结果时,就会返回结果
// 意外,当在resolved之前,有一个rejected,会直接变成rejected
const promise = Promise.race([p1,p2,p3])
promise.then(res => {
  console.log(res); // 111
}).catch(err => {
  console.log(err);
})

Promise类的any方法

// 创建多个Promise
const p1 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve(111)
  },1000)
})

const p2 = new Promise((resolve,reject) => {
  setTimeout(() => {
    reject(222)
  },200)
})

const p3 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve(333)
  },500)
})

// any方法
// 只有当有resolve有结果的时候才会打印结果,
// 当所有promise都是rejected时,才会进入catch
Promise.any([p1,p2,p3]).then(res => {
  console.log(res); // 333
}).catch(err=> {
  console.log('err:',err.errors); 
})

手写一个Promise

1. 结构的设计

// Promise A+规范地址 https://promiseaplus.com/

// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'

class HPromise {
  constructor(executor) {
    this.status = PROMISE_STATUS_PENDING // 整个promise的状态
    this.value = undefined // resolve接受的参数
    this.reason = undefined // reject接受的参数

    const resolve = (value) => {
      if(this.status === PROMISE_STATUS_PENDING) {
        this.status = PROMISE_STATUS_FULFILLED
        this.value = value
        console.log('resolve被调用');
        // 这里还要执行then传入的第一个回调函数
      }
    }
    const reject = (reason) => {
      if(this.status === PROMISE_STATUS_PENDING) {
        this.status = PROMISE_STATUS_REJECTED
        this.reason = reason
        console.log('reject被调用');
        // 这里还要执行then传入的第二个回调函数
      }
    }

    executor(resolve,reject)
  }
}

const promise = new HPromise((resolve,reject) => {
  console.log('状态pending');
  resolve(1111)
})

then方法设计

// Promise A+规范地址 https://promiseaplus.com/

// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'

class HPromise {
  constructor(executor) {
    this.status = PROMISE_STATUS_PENDING // 整个promise的状态
    this.value = undefined // resolve接受的参数
    this.reason = undefined // reject接受的参数

    const resolve = (value) => {
      if(this.status === PROMISE_STATUS_PENDING) {
        this.status = PROMISE_STATUS_FULFILLED
        // queueMicrotask把一个函数加到微任务当中
        queueMicrotask(() => {
          this.value = value
          this.onFulfilled(this.value)
        })
      }
    }
    const reject = (reason) => {
      if(this.status === PROMISE_STATUS_PENDING) {
        this.status = PROMISE_STATUS_REJECTED
        queueMicrotask(() => {
          this.reason = reason
          this.onFulfilled(this.reason)
        })
      }
    }

    executor(resolve,reject)
  }

  then(onFulfilled, onRejected) {
    this.onFulfilled = onFulfilled
    this.onRejected = onRejected
  }
}

const promise = new HPromise((resolve,reject) => {
  console.log('状态pending');
  resolve('1111')
  reject('22222')
})

promise.then(res => {
  console.log('res:',res);
},err => {
  console.log('err:',err);
})

then方法优化一

优化当状态确认后的then调用

// Promise A+规范地址 https://promiseaplus.com/

// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'

class HPromise {
  constructor(executor) {
    this.status = PROMISE_STATUS_PENDING // 整个promise的状态
    this.value = undefined // resolve接受的参数
    this.reason = undefined // reject接受的参数
    this.onFulfilledFns = []
    this.onRejectedFns = []

    const resolve = (value) => {
      if(this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if(this.status !== PROMISE_STATUS_PENDING)return
          this.status = PROMISE_STATUS_FULFILLED
          this.value = value
          this.onFulfilledFns.forEach(fn => fn(this.value))
        })
      }
    }
    const reject = (reason) => {
      if(this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if(this.status !== PROMISE_STATUS_PENDING)return 
          this.status = PROMISE_STATUS_REJECTED
          this.reason = reason
          this.onRejectedFns.forEach(fn => fn(this.reason))
        })
      }
    }
    executor(resolve,reject)
  }
  // then方法实现
  then(onFulfilled, onRejected) {
    // 当状态已经确定,就直接执行传入的函数
    if(this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
      onFulfilled(this.value)
    }
    // 当状态已经确定,就直接执行传入的函数
     if(this.status === PROMISE_STATUS_REJECTED && onRejected) {
      onRejected(this.reason)
    }

    if(this.status === PROMISE_STATUS_PENDING) {
      this.onFulfilledFns.push(onFulfilled)
      this.onRejectedFns.push(onRejected)
    }
  }
}

const promise = new HPromise((resolve,reject) => {
  console.log('状态pending');
  resolve('1111')
  reject('22222')
})

// 多次then的调用
promise.then(res => {
  console.log('res1:',res);
},err => {
  console.log('err1:',err);
})

promise.then(res => {
  console.log('res2:',res);
},err => {
  console.log('err2:',err);
})


// 在确定promise状态后,再次调用
setTimeout(() => {
  promise.then(res => {
    console.log('res3:',res);
  },err => {
    console.log('err3:',err);
  })
},1000)

then方法优化二

实现then方法的链式调用

// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'

// 封装一个捕获函数执行异常的工具函数
function execFnWithCatchError(fn, value, resolve, reject) {
  try {
    const result = fn(value)
    resolve(result)
  } catch (error) {
    reject(error)
  }
}

class HPromise {
  constructor(executor) {
    this.status = PROMISE_STATUS_PENDING // 整个promise的状态
    this.value = undefined // resolve接受的参数
    this.reason = undefined // reject接受的参数
    this.onFulfilledFns = []
    this.onRejectedFns = []

    const resolve = (value) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_FULFILLED
          this.value = value
          this.onFulfilledFns.forEach(fn => fn())
        })
      }
    }
    const reject = (reason) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_REJECTED
          this.reason = reason
          this.onRejectedFns.forEach(fn => fn())
        })
      }
    }
    try {
      executor(resolve, reject)
    } catch (error) {
      reject(error)
    }
  }
  // then方法实现
  then(onFulfilled, onRejected) {
    return new HPromise((resolve, reject) => {
      // 当状态已经确定,就直接执行传入的函数
      if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
        execFnWithCatchError(onFulfilled, this.value, resolve, reject)
      }
      // 当状态已经确定,就直接执行传入的函数
      if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
        execFnWithCatchError(onRejected, this.reason, resolve, reject)
      }

      if (this.status === PROMISE_STATUS_PENDING) {
        this.onFulfilledFns.push(() => {
          execFnWithCatchError(onFulfilled, this.value, resolve, reject)
        })
        this.onRejectedFns.push(() => {
          execFnWithCatchError(onRejected, this.reason, resolve, reject)
        })
      }
    })

  }
}

const promise = new HPromise((resolve, reject) => {
  console.log('状态pending');
  resolve('1111')
  // reject('22222')
})

promise.then(res => {
  console.log('res:', res);
  // throw new Error('错误异常')
  return 'aaaa'
}, err => {
  console.log('err:', err);
}).then(res => {
  console.log('res1:', res);
  return 'bbbb'
}, err => {
  console.log('err1:', err);
}).then(res => {
  console.log('res2:', res);
}, err => {
  console.log('err2:', err);
})

catch方法设计

// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'

// 封装一个捕获函数执行异常的工具函数
function execFnWithCatchError(fn, value, resolve, reject) {
  try {
    const result = fn(value)
    resolve(result)
  } catch (error) {
    reject(error)
  }
}

class HPromise {
  constructor(executor) {
    this.status = PROMISE_STATUS_PENDING // 整个promise的状态
    this.value = undefined // resolve接受的参数
    this.reason = undefined // reject接受的参数
    this.onFulfilledFns = []
    this.onRejectedFns = []

    const resolve = (value) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_FULFILLED
          this.value = value
          this.onFulfilledFns.forEach(fn => fn())
        })
      }
    }
    const reject = (reason) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_REJECTED
          this.reason = reason
          this.onRejectedFns.forEach(fn => fn())
        })
      }
    }
    try {
      executor(resolve, reject)
    } catch (error) {
      reject(error)
    }
  }
  // then方法实现
  then(onFulfilled, onRejected) {
    // 判断当前then方法有没有处理异常,如果没有处理,交给后面的方法(then,catch)处理
    onRejected = onRejected || (err => {throw err})

    return new HPromise((resolve, reject) => {
      // 当状态已经确定,就直接执行传入的函数
      if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
        execFnWithCatchError(onFulfilled, this.value, resolve, reject)
      }
      // 当状态已经确定,就直接执行传入的函数
      if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
        execFnWithCatchError(onRejected, this.reason, resolve, reject)
      }

      if (this.status === PROMISE_STATUS_PENDING) {
        onFulfilled && this.onFulfilledFns.push(() => {
          execFnWithCatchError(onFulfilled, this.value, resolve, reject)
        })
        onRejected && this.onRejectedFns.push(() => {
          execFnWithCatchError(onRejected, this.reason, resolve, reject)
        })
      }
    })
  }

  // catch方法的实现
  catch(onRejected) {
    this.then(undefined,onRejected)
  }
}

const promise = new HPromise((resolve, reject) => {
  console.log('状态pending');
  resolve('1111')
  // reject('22222')
})

promise.then(res => {
  console.log('res:', res);
  throw new Error('错误异常')
  return 'aaaa'
}, err => {
  console.log('err1:', err);
}).catch(err => {
  console.log('err:',err);
})

finally方法设计

// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'

// 封装一个捕获函数执行异常的工具函数
function execFnWithCatchError(fn, value, resolve, reject) {
  try {
    const result = fn(value)
    resolve(result)
  } catch (error) {
    reject(error)
  }
}

class HPromise {
  constructor(executor) {
    this.status = PROMISE_STATUS_PENDING // 整个promise的状态
    this.value = undefined // resolve接受的参数
    this.reason = undefined // reject接受的参数
    this.onFulfilledFns = []
    this.onRejectedFns = []

    const resolve = (value) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_FULFILLED
          this.value = value
          this.onFulfilledFns.forEach(fn => fn())
        })
      }
    }
    const reject = (reason) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_REJECTED
          this.reason = reason
          this.onRejectedFns.forEach(fn => fn())
        })
      }
    }
    try {
      executor(resolve, reject)
    } catch (error) {
      reject(error)
    }
  }
  // then方法实现
  then(onFulfilled, onRejected) {
    // 判断当前有没有传进来两个函数
    onRejected = onRejected || (err => { throw err })
    onFulfilled = onFulfilled || (value => value)

    return new HPromise((resolve, reject) => {
      // 当状态已经确定,就直接执行传入的函数
      if (this.status === PROMISE_STATUS_FULFILLED) {
        execFnWithCatchError(onFulfilled, this.value, resolve, reject)
      }
      // 当状态已经确定,就直接执行传入的函数
      if (this.status === PROMISE_STATUS_REJECTED) {
        execFnWithCatchError(onRejected, this.reason, resolve, reject)
      }

      if (this.status === PROMISE_STATUS_PENDING) {
        this.onFulfilledFns.push(() => {
          execFnWithCatchError(onFulfilled, this.value, resolve, reject)
        })
        this.onRejectedFns.push(() => {
          execFnWithCatchError(onRejected, this.reason, resolve, reject)
        })
      }
    })
  }

  // catch方法的实现
  catch(onRejected) {
    // 给catch返回一个promise
    return this.then(undefined, onRejected)
  }

  // finally方法的实现
  finally(onFinally) {
    // 把当前finally要执行的函数传进去
    this.then(() => onFinally(), () => onFinally())
  }
}

const promise = new HPromise((resolve, reject) => {
  console.log('状态pending');
  resolve('1111')
  // reject('22222')
})

promise.then(res => {
  console.log('res:', res);
  // throw new Error('错误异常')
  return 'aaaa'
}).catch(err => {
  console.log('err:', err);
}).finally(() => {
  console.log('finally');
})

Promise类方法 resolve reject

// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'

// 封装一个捕获函数执行异常的工具函数
function execFnWithCatchError(fn, value, resolve, reject) {
  try {
    const result = fn(value)
    resolve(result)
  } catch (error) {
    reject(error)
  }
}

class HPromise {
  constructor(executor) {
    this.status = PROMISE_STATUS_PENDING // 整个promise的状态
    this.value = undefined // resolve接受的参数
    this.reason = undefined // reject接受的参数
    this.onFulfilledFns = []
    this.onRejectedFns = []

    const resolve = (value) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_FULFILLED
          this.value = value
          this.onFulfilledFns.forEach(fn => fn())
        })
      }
    }
    const reject = (reason) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_REJECTED
          this.reason = reason
          this.onRejectedFns.forEach(fn => fn())
        })
      }
    }
    try {
      executor(resolve, reject)
    } catch (error) {
      reject(error)
    }
  }
  // then方法实现
  then(onFulfilled, onRejected) {
    // 判断当前有没有传进来两个函数
    onRejected = onRejected || (err => { throw err })
    onFulfilled = onFulfilled || (value => value)

    return new HPromise((resolve, reject) => {
      // 当状态已经确定,就直接执行传入的函数
      if (this.status === PROMISE_STATUS_FULFILLED) {
        execFnWithCatchError(onFulfilled, this.value, resolve, reject)
      }
      // 当状态已经确定,就直接执行传入的函数
      if (this.status === PROMISE_STATUS_REJECTED) {
        execFnWithCatchError(onRejected, this.reason, resolve, reject)
      }

      if (this.status === PROMISE_STATUS_PENDING) {
        this.onFulfilledFns.push(() => {
          execFnWithCatchError(onFulfilled, this.value, resolve, reject)
        })
        this.onRejectedFns.push(() => {
          execFnWithCatchError(onRejected, this.reason, resolve, reject)
        })
      }
    })
  }

  // catch方法的实现
  catch(onRejected) {
    // 给catch返回一个promise
    return this.then(undefined, onRejected)
  }

  // finally方法的实现
  finally(onFinally) {
    // 把当前finally要执行的函数传进去
    this.then(() => onFinally(), () => onFinally())
  }

  static resolve(value) {
    return new HPromise(resovle => resovle(value))
  }

  static reject(season) {
    return new HPromise(reject => reject(season))
  }
}

HPromise.resolve('Hello World').then(res => {
  console.log('res:',res);
})

HPromise.reject('Error Message').then(err => {
  console.log('err:',err);
})


Promise类方法 all allSettled

// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'

// 封装一个捕获函数执行异常的工具函数
function execFnWithCatchError(fn, value, resolve, reject) {
  try {
    const result = fn(value)
    resolve(result)
  } catch (error) {
    reject(error)
  }
}

class HPromise {
  constructor(executor) {
    this.status = PROMISE_STATUS_PENDING // 整个promise的状态
    this.value = undefined // resolve接受的参数
    this.reason = undefined // reject接受的参数
    this.onFulfilledFns = []
    this.onRejectedFns = []

    const resolve = (value) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_FULFILLED
          this.value = value
          this.onFulfilledFns.forEach(fn => fn())
        })
      }
    }
    const reject = (reason) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_REJECTED
          this.reason = reason
          this.onRejectedFns.forEach(fn => fn())
        })
      }
    }
    try {
      executor(resolve, reject)
    } catch (error) {
      reject(error)
    }
  }
  // then方法实现
  then(onFulfilled, onRejected) {
    // 判断当前有没有传进来两个函数
    onRejected = onRejected || (err => { throw err })
    onFulfilled = onFulfilled || (value => value)

    return new HPromise((resolve, reject) => {
      // 当状态已经确定,就直接执行传入的函数
      if (this.status === PROMISE_STATUS_FULFILLED) {
        execFnWithCatchError(onFulfilled, this.value, resolve, reject)
      }
      // 当状态已经确定,就直接执行传入的函数
      if (this.status === PROMISE_STATUS_REJECTED) {
        execFnWithCatchError(onRejected, this.reason, resolve, reject)
      }

      if (this.status === PROMISE_STATUS_PENDING) {
        this.onFulfilledFns.push(() => {
          execFnWithCatchError(onFulfilled, this.value, resolve, reject)
        })
        this.onRejectedFns.push(() => {
          execFnWithCatchError(onRejected, this.reason, resolve, reject)
        })
      }
    })
  }

  // catch方法的实现
  catch(onRejected) {
    // 给catch返回一个promise
    return this.then(undefined, onRejected)
  }

  // finally方法的实现
  finally(onFinally) {
    // 把当前finally要执行的函数传进去
    this.then(() => onFinally(), () => onFinally())
  }

  static resolve(value) {
    return new HPromise(resovle => resovle(value))
  }

  static reject(season) {
    return new HPromise(reject => reject(season))
  }
  static all(parmises) {
    // 问题关键: 什么时候执行resolve,什么时候执行reject
    const values = []
    return new HPromise((resolve, reject) => {
      parmises.forEach(parmise => {
        parmise.then(res => {
          values.push(res)
          if (values.length === parmises.length) {
            resolve(res)
          }
        }, err => {
          reject(err)
        })
      })
    })
  }
  // 只有当所有的promise都有返回值后,才会再resolve里拿到所有的结果和状态
  static allSettled(parmises) {
    return new HPromise(resolve => {
      const values = []
      parmises.forEach(parmise => {
        parmise.then(res => {
          values.push({status: PROMISE_STATUS_FULFILLED,value:res})
          if(values.length === parmises.length) {
            resolve(values)
          }
        },err => {
          values.push({status: PROMISE_STATUS_REJECTED,value:err})
          if(values.length === parmises.length) {
            resolve(values)
          }
        })
      })
    })
  }
}


const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(111)
  }, 1000)
})

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(222)
  }, 2000)
})

const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(333)
  }, 3000)
})

// Promise.all([p2, p1, p3]).then(res => {
//   console.log('res:', res);
// }).catch(err => {
//   console.log('err:', err);
// })


Promise.allSettled([p1,p2,p3]).then(res => {
  console.log('res:',res);
},err => {
  console.log('err:',err);
})


Promise类方法 any race

// promise 状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'

// 封装一个捕获函数执行异常的工具函数
function execFnWithCatchError(fn, value, resolve, reject) {
  try {
    const result = fn(value)
    resolve(result)
  } catch (error) {
    reject(error)
  }
}

class HPromise {
  constructor(executor) {
    this.status = PROMISE_STATUS_PENDING // 整个promise的状态
    this.value = undefined // resolve接受的参数
    this.reason = undefined // reject接受的参数
    this.onFulfilledFns = []
    this.onRejectedFns = []

    const resolve = (value) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_FULFILLED
          this.value = value
          this.onFulfilledFns.forEach(fn => fn())
        })
      }
    }
    const reject = (reason) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务
        queueMicrotask(() => {
          // 先判断状态是否是pending状态,如果不是就不再执行下面的代码
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_REJECTED
          this.reason = reason
          this.onRejectedFns.forEach(fn => fn())
        })
      }
    }
    try {
      executor(resolve, reject)
    } catch (error) {
      reject(error)
    }
  }
  // then方法实现
  then(onFulfilled, onRejected) {
    // 判断当前有没有传进来两个函数
    onRejected = onRejected || (err => { throw err })
    onFulfilled = onFulfilled || (value => value)

    return new HPromise((resolve, reject) => {
      // 当状态已经确定,就直接执行传入的函数
      if (this.status === PROMISE_STATUS_FULFILLED) {
        execFnWithCatchError(onFulfilled, this.value, resolve, reject)
      }
      // 当状态已经确定,就直接执行传入的函数
      if (this.status === PROMISE_STATUS_REJECTED) {
        execFnWithCatchError(onRejected, this.reason, resolve, reject)
      }

      if (this.status === PROMISE_STATUS_PENDING) {
        this.onFulfilledFns.push(() => {
          execFnWithCatchError(onFulfilled, this.value, resolve, reject)
        })
        this.onRejectedFns.push(() => {
          execFnWithCatchError(onRejected, this.reason, resolve, reject)
        })
      }
    })
  }

  // catch方法的实现
  catch(onRejected) {
    // 给catch返回一个promise
    return this.then(undefined, onRejected)
  }

  // finally方法的实现
  finally(onFinally) {
    // 把当前finally要执行的函数传进去
    this.then(() => onFinally(), () => onFinally())
  }

  static resolve(value) {
    return new HPromise(resovle => resovle(value))
  }

  static reject(season) {
    return new HPromise(reject => reject(season))
  }
  static all(parmises) {
    // 问题关键: 什么时候执行resolve,什么时候执行reject
    const values = []
    return new HPromise((resolve, reject) => {
      parmises.forEach(parmise => {
        parmise.then(res => {
          values.push(res)
          if (values.length === parmises.length) {
            resolve(res)
          }
        }, err => {
          reject(err)
        })
      })
    })
  }
  // 只有当所有的promise都有返回值后,才会再resolve里拿到所有的结果和状态
  static allSettled(parmises) {
    return new HPromise(resolve => {
      const values = []
      parmises.forEach(parmise => {
        parmise.then(res => {
          values.push({ status: PROMISE_STATUS_FULFILLED, value: res })
          if (values.length === parmises.length) {
            resolve(values)
          }
        }, err => {
          values.push({ status: PROMISE_STATUS_REJECTED, value: err })
          if (values.length === parmises.length) {
            resolve(values)
          }
        })
      })
    })
  }
  // 当几个promise有一个resovled结果时,就会返回结果
  // 意外,当在resolved之前,有一个rejected,会直接变成rejected
  static race(parmises) {
    return new HPromise((resolve, reject) => {
      parmises.forEach(parmise => {
        // parmise.then(res => resolve(res), err=> reject(err))
        parmise.then(resolve, reject)
      })
    })
  }


  // any方法
  // 只有当有resolve有结果的时候才会打印结果,
  // 当所有promise都是rejected时,才会进入catch
  static any(parmises) { 
    const reasons = []
    return new HPromise((resolve,reject) => {
      parmises.forEach(parmise => {
        parmise.then(resolve, err => {
          reasons.push(err)
          if(reasons.length === parmises.length) {
            reject(new AggregateError(reasons))
          }
        })
      })
    })
  }

}



const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(111)
  }, 3000)
})

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(222)
  }, 2000)
})

const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(333)
  }, 3000)
})

// HPromise.race([p1, p2, p3]).then(res => {
//   console.log('res:', res);
// }, err => {
//   console.log('err:', err);
// })

HPromise.any([p1, p2, p3]).then(res => {
  console.log('res:', res);
}, err => {
  console.log('err:', err.errors);
})

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

派大星965

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值