david2tdw / blog

学习记录
1 stars 1 forks source link

[JS] Promise实现 #190

Open david2tdw opened 4 years ago

david2tdw commented 4 years ago
// testPromise1.js
/**
 * 异步实现
 */
const resolvePromise = (promise2, x, resolve, reject) => {
  if (x instanceof MyPromise) {
    const then = x.then
    if (x.status === MyPromise.PENDING) {
      // promise pending
      then.call(x, y => { // x的then方法传2个参数
        resolvePromise(promise2, y, resolve, reject)
      }), err => {
        reject(err)
      }
    } else {
      // promise resolved, rejected
      x.then(resolve, reject)
    }
  } else  {
    // 非promise resolved, rejected
    resolve(x)
  }
}

class MyPromise {
  static PENDING = 'pending';
  static RESOLVED = 'resolved';
  static REJECTED = 'rejected';

  constructor (executor) {
    this.status = MyPromise.PENDING;
    // 用于保存 resolve 的值
    this.value = null;
    // 用于保存 reject 的值
    this.reason = null;
    // 用于保存 then 的成功回调
    this.onFulfilled = null;
    // 用于保存 then 的失败回调
    this.onRejected = null;

    this.resolvedQueues = [];
    this.rejectedQueues = [];

    // executor 的 resolve 参数
    // 用于改变状态 并执行 then 中的成功回调
    let resolve = value => {
      this.value = value;

      this.status = MyPromise.RESOLVED
      this.resolvedQueues.forEach(cb => cb(this.value))
      // this.onFulfilled && this.onFulfilled(this.value);
    }

    // executor 的 reject 参数
    // 用于改变状态 并执行 then 中的失败回调
    let reject = reason => {
      this.reason = reason;
      this.status = MyPromise.REJECTED
      this.rejectedQueues.forEach(cb => cb(this.reason))
      // this.onRejected && this.onRejected(this.reason);
    }

    // 执行 executor 函数
    // 将我们上面定义的两个函数作为参数 传入
    // 有可能在 执行 executor 函数的时候会出错,所以需要 try catch 一下 
    try {
      executor(resolve, reject);
    } catch(err) {
      reject(err);
    }
  }

  // 定义 then 函数
  // 并且将 then 中的参数复制给 this.onFulfilled 和 this.onRejected
  then(onFulfilled, onRejected) {
    // this.onFulfilled = onFulfilled;
    // this.onRejected = onRejected;
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
    onRejected = typeof onRejected === 'function' ? onRejected: reason => {throw reason}

    // return this返回当前对象,会导致promise的status不再发生变化

    // if (this.status === MyPromise.PENDING) {
    //   this.resolvedQueues.push(onFulfilled)
    //   this.rejectedQueues.push(onRejected)
    // }

    // if (this.status === MyPromise.RESOLVED) {
    //   onFulfilled(this.value)
    // }

    // if (this.status === MyPromise.REJECTED) {
    //   onRejected(this.reason)
    // }
    // return this

    // 返回了一个新的 Promise 对象
    const promise2 = new MyPromise((resolve, reject) => {
      // 成功状态,直接 resolve
      if (this.status === MyPromise.RESOLVED) {
        // 将 onFulfilled 函数的返回值,resolve 出去
        let x = onFulfilled(this.value)
        resolvePromise(promise2, x, resolve, reject)
        // resolve(x)
      }
      if (this.status === MyPromise.REJECTED) {
        let x = onRejected(this.reason)
        resolvePromise(promise2, x, resolve, reject)
        // reject & reject(x)
      }

      // 等待状态,将 onFulfilled,onRejected 塞入数组中,等待回调执行
      if (this.status === MyPromise.PENDING) {
        this.resolvedQueues.push(value => {
          let x = onFulfilled(value)
          resolvePromise(promise2, x, resolve, reject)
          // resolve(x)
        })
        this.rejectedQueues.push(reason => {
          let x = onRejected(reason)
          resolvePromise(promise2, x, resolve, reject)
          // reject(x)
        })
      }
    })
    return promise2
  }
}

module.exports = MyPromise

let p1 = new MyPromise((resolved, reject) => {
  setTimeout(() => {
    resolved('成功了');
  }, 3000);
})

// p1.then().then((data) => {
//   console.log(data);
// }, (err) => {
//   console.log(err);
// })

p1.then(res => {
  console.log('123')
  return 'then1'
})
.then(res => {
  console.log(res)
  return 'then2'
})
.then(res => {
  console.log(res)
  return 'then3'
})

p1.then((res) => {
  console.log(res + 'xxx');
  return new MyPromise((resolved, rejected) => {
    setTimeout(() => {
      resolved('async then1');
    }, 1000)
  });
})
.then((res) => {
  console.log(res);
  return new MyPromise((resolved, rejected) => {
    setTimeout(() => {
      resolved('async then2');
    }, 1000)
  });
})
.then((res) => {
  console.log(res);
  return 'async then3';
})

node运行:

$ node testPromise1.js

30分钟,带你实现一个符合规范的 Promise(巨详细)