Promise学习笔记 以及手写附带的 各种静态函数

 1、Promise 对象的 初始化的过程

const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
  constructor(exec) {
    if (typeof exec !== 'function') {
      throw new TypeError(`Promise resolver ${exec} is not a function`)
    }
    this.bindFunc()
    this.initValue()
    try {
      exec(this.resolve, this.reject) // 立即执行的回调函数
    } catch (error) {
      this.reject(error)
    }
  }
  resolve(value) {
        // 如果状态是等待的话,就 允许改变状态
    if (this.status === PENDING) {
      this.status = FULFILLED
      this.value = value
      this.onFulfilledCallbacks.forEach(cb => {
        cb(this.value)
      })
    }
  }
  reject(reason) {
    if (this.status === PENDING) {
      this.status = REJECTED
      this.reason = reason
      this.onRejectedCallbacks.forEach(cb => {
        cb(this.reason)
      })
    }
  }
  bindFunc() {
    this.resolve = this.resolve.bind(this)
    this.reject = this.reject.bind(this)
  }
  initValue() {
    this.status = PENDING   // 初始化的值
    this.value = undefined // 成功的值
    this.reason = undefined // 失败的原因
    this.onFulfilledCallbacks = [] // 成功回调
    this.onRejectedCallbacks = [] // 失败回调
  }
}

说实话,一开始有很好为什么这里的回调要使用数组

使用情况如下

const p = new Promise((resolve) => {resolve(1)})
p.then(() => {})
p.then(() => {})
p.then(() => {})
p.then(() => {})

2、Promise 的 .then 方法定义

class MyPromise {
  ...
  then(onFulfilled, onRejected) {
    // 可能有这种情况,也就是没有传 成功和失败函数
    //  .then().then().then((v) => {console.log(v)})
    if (typeof onFulfilled !== 'function') {
        onFulfilled = (value) => value
    }
    if (typeof onRejected !== 'function') {
        onRejected = (reason) => { throw reason }
    }
    let promise2 =  new MyPromise((resolve, reject) => {
      if (this.status === FULFILLED) {
        // 使用异步代码是为了 能够 在 resolvePromise 中 获取到 promise2
        setTimeout(() => {
          // 这里由于 前面使用了箭头函数,所以这里的 value 其实还是上一个 Promise 的 value
          // 上一个 promise 的返回值,也就是下一个回调函数 传入的值
          // 如果是普通值,直接调用 resole,这样就能实现链式调用 接下来的 then
          // 如果 是 promise,查看 promise 对象返回的结果
          // 再根据promise对象返回的结果,决定调用 resolve 还是 reject
          try {
            let x = onFulfilled(this.value)
            MyPromise.resolvePromise(x, promise2, resolve, reject)
          } catch (e) {
            // 把错误传给接下来的 then
            reject(e)
          }
        }, 0)
        // resolve(x)
      } else if (this.status === REJECTED) {
        setTimeout(() => {
          // 上一个 promise 的返回值,也就是下一个回调函数 传入的值
          // 如果是普通纸,直接调用 resole,这样就能实现链式调用 接下来的 then
          // 如果 是 promise,查看 promise 对象返回的结果
          // 再更具promise对象返回的结果,决定调用 resolve 还是 reject
          try {
            let x = onRejected(this.reason)
            MyPromise.resolvePromise(x, promise2, resolve, reject)
          } catch (e) {
            // 把错误传给接下来的 then
            reject(e)
          }
        }, 0)
      } else {
      // 等待,将成功的回调和 失败的回调 存储起来
      this.onFulfilledCallbacks.push(() => {
          setTimeout(() => {
            // 上一个 promise 的返回值,也就是下一个回调函数 传入的值
            // 如果是普通纸,直接调用 resole,这样就能实现链式调用 接下来的 then
            // 如果 是 promise,查看 promise 对象返回的结果
            // 再更具promise对象返回的结果,决定调用 resolve 还是 reject
            try {
              let x = onFulfilled(this.value)
              MyPromise.resolvePromise(x, promise2, resolve, reject)
            } catch (e) {
              // 把错误传给接下来的 then
              reject(e)
            }
          }, 0)
        })
        this.onRejectedCallbacks.push(() => {
          setTimeout(() => {
            // 上一个 promise 的返回值,也就是下一个回调函数 传入的值
            // 如果是普通纸,直接调用 resole,这样就能实现链式调用 接下来的 then
            // 如果 是 promise,查看 promise 对象返回的结果
            // 再更具promise对象返回的结果,决定调用 resolve 还是 reject
            try {
              let x = onRejected(this.reason)
              MyPromise.resolvePromise(x, promise2, resolve, reject)
            } catch (e) {
              // 把错误传给接下来的 then
              reject(e)
            }
          }, 0)
        })
      }
    })
    return promise2
  }
  // 统一解决 .then 的返回值
  // 这里写的比较简单,但是主要功能已经体现
  // 也就是当 返回值为 Promise 的时候
  static resolvePromise(x, promise2, resolve, reject) {
    if (x === promise2) {
      return reject(new TypeError('不能循环调用promise'))
    }
    if (x instanceof MyPromise) {
      // 就是 promise 对象
      // 这样就能把当前的 执行返回结果 当做返回值,丢给接下来的 .then
      // 相当于 把之前 .then 的执行权力 交给了 这个 x
      x.then(resolve, reject)
    } else {
      resolve(x)
    }
  }
  ...
}

以上,promise的主体其实就完成了,接下来就是附带的那些函数了

3、Promise 的 catch

class MyPromise {
   ...
  catch(callback) {
    return this.then(undefined, callback)
  }
  ...
}

4、Promise 的 finally

class MyPromise {
   ...
  finally(callback) {
    return this.then(
      value => {
      // 如果 callback 返回的是一个 promise ,那么就会直接返回 那个 promise
      // 要注意的是,finally 是获取不到 promise 的 value 的
      return new MyPromise.resolve(callback()).then(() => value)
    }, reason => {
      return new MyPromise.resolve(callback()).then(() => {throw reason})
    })
  }
  ...
}

5、Promise.resolve() 静态函数

class MyPromise {
   ...
  // 如果传入进来的是 一个 promise ,那么 就直接使用这个 promise
  static resolve (value) {
    if (value instanceof MyPromise) {
      return value
    } else {
      return new MyPromise(resolve => resolve(value))
    }
  }
  ...
}

6、Promise.all() 静态函数

class MyPromise {
   ...
  static all(promises) {
    let result = []
    let length = 0
    return new MyPromise((resolve, reject) => {
      function addData(key, value) {
        result[key] = value
        length ++
        // 等到所有值都获取完毕了,就可以结束了
        if (length === promises.length) {
          resolve(result)
        }
      }
      for (let i = 0; i < promises.length; i++) {
        const current = promises[i];
        // 是 promise 对象的话,就执行 promise
        if (current instanceof MyPromise) {
          current.then((value) => {
              addData(i, value)
          }, reject)
        } else {
          // 普通值
          addData(i, current)
        }
      }
    })
  }
  ...
}

7、Promise.race() 静态函数

class MyPromise {
   ...
  static race(promises) {
    return new MyPromise((resolve, reject) => {
      // race 只需要返回第一个值就可以了
      for (let i = 0; i < promises.length; i++) {
        const current = promises[i];
        // 是 promise 对象的话,就执行 promise
        if (current instanceof MyPromise) {
          current.then((value) => {
            resolve(value)
          }, reject)
        } else {
          // 普通值
          resolve(current)
        }
      }
    })
  }
  ...
}

 

8、Promise.allSettled() 静态函数

class MyPromise {
   ...
  static allSettled(promises) {
    let result = []
    let length = 0
    return new MyPromise((resolve, reject) => {
      function addData(key, value, status) {
        result[key] = {
          [status === FULFILLED ? 'value' : 'reason']: value,
          status
        }
        length ++
        // 等到所有值都获取完毕了,就可以结束了
        if (length === promises.length) {
          resolve(result)
        }
      }
      for (let i = 0; i < promises.length; i++) {
        const current = promises[i];
        // 是 promise 对象的话,就执行 promise
        if (current instanceof MyPromise) {
          // 无论是成功还是失败,都会将 返回值放到需要返回的数组中,集中返回
          current.then(
            (value) => { addData(i, value, FULFILLED) }, 
            (reason) => { addData(i, reason, REJECTED) }
          )
        } else {
          // 普通值
          addData(i, current, FULFILLED)
        }
      }
    })
  }
  ...
}

 

 

 

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值