视频:https://www.bilibili.com/video/av84485368?t=232&p=18&spm_id_from=333.334.b_62696c692d6865616465722d6d.22

手写PROMISE核心代码,提升JAVASCRIPT编程能力,加深JS异步任务理解,ES6必学知识

代码写在 HD.js 里

HD.js

class HD {
  static PENDING = 'pending'; // 准备
  static FUlFILLED = 'fulfilled'; // 解决
  static REJECTED = 'rejected'; // 拒绝
  constructor(executor) {
    this.status = HD.PENDING;
    this.value = null;
    this.callbacks = [];
    try {
      executor(this.resolve.bind(this), this.reject.bind(this));
    } catch (error) {
      this.reject(error);
    }
  }

  resolve(value) {
    // 异步特性
    if (this.status == HD.PENDING) {
      this.status = HD.FUlFILLED;
      this.value = value;
      // 让与resolve同块的方法先执行
      setTimeout(() => {
        // 处理准备时期 then 放入的回调
        this.callbacks.forEach(callback => {
          callback['onFulfilled'](value);
        })
      })
    }
  }

  reject(reason) {
    // 异步特性
    if (this.status == HD.PENDING) {
      this.status = HD.REJECTED;
      this.value = reason;
      // 让与resolve同块的方法先执行
      setTimeout(() => {
        // 处理准备时期 then 放入的回调
        this.callbacks.forEach(callback => {
          callback['onRejected'](reason);
        })
      })
    }
  }

  then(onFulfilled, onRejected) {
    // 没传resolve方法
    if (typeof onFulfilled != 'function') {
      // then值穿透
      onFulfilled = () => this.value;
    }
    // 没传reject方法
    if (typeof onRejected != 'function') {
      // 没有catch异常
      onRejected = function () {
        throw new Error("Unexpected end of input")
      }
    }
    let promise = new HD((resolve, reject) => {
      // 准备
      if (this.status == HD.PENDING) {
        this.callbacks.push({
          onFulfilled: value => {
            // 冗余代码的优化
            HD.parse(promise, onFulfilled(value), resolve, reject)
          },
          onRejected: reason => {
            // 冗余代码的优化
            HD.parse(promise, onRejected(reason), resolve, reject)
          }
        });
      }
      // 处理
      else if (this.status == HD.FUlFILLED) {
        // 等待this.next赋值
        setTimeout(() => {
          // 冗余代码的优化
          HD.parse(promise, onFulfilled(this.value), resolve, reject)
        })
      }
      // 拒绝
      else if (this.status == HD.REJECTED) {
        // 等待this.next赋值
        setTimeout(() => {
          // 冗余代码的优化
          HD.parse(promise, onRejected(this.value), resolve, reject)
        })
      }
    });

    return promise;
  }

  static parse(promise, result, resolve, reject) {
    // 禁止同一个then中循环返回 promise
    if (promise == result) {
      throw new TypeError('Chaining cycle detected')
    }
    try {
      // 设置结果值
      if (result instanceof HD) {
        result.then(resolve, reject);
      } else {
        resolve(result);
      }
    } catch (error) {
      reject(error);
    }
  }

  static resolve(value) {
    return new HD((resolve, reject) => {
      HD.parse(null, value, resolve, reject);
    })
  }
  static reject(value) {
    return new HD((resolve, reject) => {
      reject(value)
    })
  }

  /** * 全成功,返回全部返回值 * 有失败,返回第一个失败信息 * @param {HD} promises */
  static all(promises) {
    return new HD((resolve, reject) => {
      const values = [];
      promises.forEach((promise) => {
        promise.then(
          value => {
            values.push(value)
            if (values.length == promises.length) {
              resolve(values);
            }
          },
          reason => {
            reject(reason)
          }
        )
      })
    })
  }

  /** * race(竞赛) * 返回第一个返回值 * @param {HD} promises */
  static race(promises) {
    return new HD((resolve, reject) => {
      promises.forEach(promise => {
        promise.then(
          value => {
            return resolve(value);
          },
          reason => {
            return reject(reason);
          }
        )
      })
    })
  }
}

race测试代码(其他自行测试吧。。)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
</body>
<script src="./dist/HD.js"></script>
<script> let p1 = new HD((resolve, reject) => { resolve('p1') }) let p2 = new HD((resolve, reject) => { resolve('p2') }) HD.race([p1, p2]).then( value => { console.log('ok', value); }, reason => { console.log('error', reason) } ) // let p1 = new Promise((resolve, reject) => { // resolve('p1') // }) // let p2 = new Promise((resolve, reject) => { // reject('p2') // }) // Promise.race([p1, p2]).then( // value => { // console.log(value); // }, // // reason => { // // console.log(reason) // // } // ) </script>

</html>