手写Promise

106 阅读1分钟

手写Promise,实现基本功能

// 手写Promise
// 定义Promise三个状态
const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';

class MyPromise {
  constructor(executor) {
    // 默认状态为pending
    this.status = PENDING;
    // 存放状态成功时的值
    this.value = undefined;
    // 存放状态失败时的值
    this.reason = undefined;

    // 存放成功的回调
    this.onResolvedCallbacks = [];
    // 存放失败的回调
    this.onRejectedCallbacks = [];

    const resolve = (value) => {
      if (this.status === PENDING) {
        this.status = FULFILLED;
        this.value = value;
        console.log(this.onResolvedCallbacks)
        this.onResolvedCallbacks.forEach(fn => fn());
      }
    }

    const reject = (reason) => {
      if (this.status === PENDING) {
        this.status = REJECTED;
        this.reason = reason;
        console.log(this.onRejectedCallbacks)
        this.onRejectedCallbacks.forEach(fn => fn());
      }
    }

    try {
      // 立即执行传入的函数
      executor(resolve, reject);
    } catch(err) {
      reject(err)
    }
  }

  then(onFulFilled, onRejected) {
    if (this.status === FULFILLED) {
      onFulFilled(this.value);
    }

    if (this.status === REJECTED) {
      onRejected(this.reason);
    }

    if (this.status === PENDING) {
      this.onResolvedCallbacks.push(() => {
        onFulFilled(this.value);
      });

      this.onRejectedCallbacks.push(() => {
        onRejected(this.reason);
      })
    }
  }
}

运行测试

  • 成功
const p1 = new MyPromise(function(resolve, reject) {
  resolve(1234)
})
p1.then((value) => {
  console.log('success:', value)
}, (err) => {
  console.log('error:', err)
})
console.log(p1)

image.png


  • 失败
const p2 = new MyPromise(function(resolve, reject) {
  reject(new Error('错误'))
})
p2.then((value) => {
  console.log('success:', value)
}, (err) => {
  console.log('error:', err)
})
console.log(p2)

image.png


  • 异步
const p3 = new MyPromise(function(resolve, reject) {
  setTimeout(() => {
    resolve('setTimeout success')
  }, 1000)
})
p3.then((value) => {
  console.log('success:', value)
}, (err) => {
  console.log('error:', err)
})
console.log(p3)

image.png