手动实现Promise

手动实现Promise

什么是Promise

Promise 是异步编程的一种解决方案,使用Promise对象可以将异步操作以同步操作的流程表达出来,同时可以解决回调地狱的问题

  • 一个Promise构造函数
// 下面这行代码表示创建了一个【形式上的】异步操作 具体是干什么的并不知道
const p = new Promise()

// 在new promise 时传入functon函数 在function中可以执行具体的异步操作 
// 这种格式叫做创建了一个具体的异步操作
const p = new Promise(function(){
  // 在这个function中 可以写具体的异步操作 
  // 如 读文件 或者发送Ajax	
})
  • Promise对象的使用
let promise = new Promise(function (reslove, reject) {
  if (true) {
    reslove("resolve函数传递的数据");// 如果执行reslove函数,那么Promise对象将从Pending状态转换为Resolved状态
  } else {
    reject("reject函数传递的数据");// 如果执行reslove函数,那么Promise对象将从Pending状态转换为Rejected状态
  }
  /*
   因为Promise对象只要new 就会立即执行,那么它执行后的状态也就会返回给实例
   在实例的then方法中,会监听Promise返回的状态,如果是Resolved状态,就会执行第一个参数(回调函数),
   如果是Rejected状态,就会执行第二个参数(回调函数)
   如果调用resolve或reject函数时带有参数,那么这些参数会传递给回调函数,也就是实例.then()中的两个回调函数
  */
})
promise.then(function (data) {
  console.log(data + "  Resolved状态的回调函数执行了");
}, function (data) {
  console.log(data + "  Reject状态的回调执行了");
})

var p1 = new Promise(function (resolve, reject) { })
var p2 = new Promise(function (resolve, reject) {
  resolve();
})
p2.then(function () {
  return "第一个回调";
}).then(function (data) {
  console.log(data);
})

  • Promise.prototype.then() 方法
    连续调用then方法:then方法被调用后会返回一个新的promise对象,并且将返回结果(如果有return)作为参数,传递给下一个回调函数
p2.then(function () {
  return "第一个回调";
}).then(function (data) {
  console.log(data);
})

手动实现Promise构造函数

//1.定义三种状态
  const PENDING = 'pending'
  const RESOLVED = 'resolved'
  const REJECTED = 'rejected'
  function MyPromise(fn) {
    this.status = PENDING;
    this.value = undefined; // 保存resolved或者rejected函数传入的参数
    this.resolvedCallbacks = []; // 里面保存的的是字符串"() => { onFulfilled(this.value)"
    this.rejectedCallbacks = [];
    const resolved = (value) => {
      // 这里获取到的value参数就是new MyPromise 时执行传入的函数中执行resolve函数传来的参数
      if (this.status == PENDING) {
        console.log("resolved执行了");
        this.status = RESOLVED;
        this.value = value;
        this.resolvedCallbacks.forEach(cb => cb());
      }
    }

    const rejected = (value) => {
      if (this.status == PENDING) {
        console.log("rejected执行了");
        this.status = REJECTED;
        this.value = value;
        this.rejectedCallbacks.forEach(cb => cb())
      }
    }
    try {
      fn(resolved, rejected);
    } catch (e) {
      console.log(e);
      rejected(e);
    }
  }

手动实现Promise.prototype.then()方法

简易版then方法,不能实现连续then
  MyPromise.prototype.then = function (onFulfilled, onRejected) {
    const that = this;
    onFulfilled = typeof onFulfilled == "function" ? onFulfilled : v => v;
    onRejected = typeof onRejected == "function" ? onRejected : r => { throw r };
    if (that.status === RESOLVED) {// 如果new MyPromise 的时候执行了resolved函数,那么应该执行then中的第一个回调函数
      onFulfilled(that.value);
    }
    if (that.status === REJECTED) {// 如果new MyPromise 的时候执行了rejected函数,那么应该执行then中的第二个回调函数
      onRejected(that.value);
    }
    // 如果是异步调用的then方法,就先不执行函数,先把函数存到数组中
    // 当 status 变化后,再遍历数组,执行函数
    if (that.status === PENDING) {
      that.resolvedCallbacks.push(() => { onFulfilled(that.value) })
      that.rejectedCallbacks.push(() => { onRejected(that.value) })
    }
  }
增强版的then函数,可以链式调用
MyPromise.prototype.then = function (onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled == "function" ? onFulfilled : v => v;
    onRejected = typeof onRejected == "function" ? onRejected : r => { throw r };
    let promise2 = new MyPromise((resolve, reject) => {
      if (this.status === RESOLVED) {
        setTimeout(() => {
          try {
            let x = onFulfilled(this.value);
            resolvePromise(x, promise2, resolve, reject);
          } catch (e) {
            reject(e);
          }
        }, 0)
        return;
      }
      if (this.status === REJECTED) {
        setTimeout(() => {
          try {
            let x = onRejected(this.value);
            resolvePromise(x, promise2, resolve, reject);
          } catch (e) {
            reject(e);
          }
        }, 0)
      }
      // 如果是异步调用的then方法,就先不执行函数,先把函数存到数组中
      // 当 status 变化后,再遍历数组,执行函数
      if (this.status === PENDING) {
        // 异步,就先不执行函数,先把函数存储到数组中
        // 当 status 变化后,在遍历数组,执行函数
        this.resolvedCallbacks.push(() => {
          setTimeout(() => {
            try {
              let x = onFulfilled(this.value);
              resolvePromise(x, promise2, resolve, reject);
            } catch (e) {
              reject(e);
            }
          }, 0);
        });

        this.rejectedCallbacks.push(() => {
          setTimeout(() => {
            try {
              let x = onRejected(this.value);
              resolvePromise(x, promise2, resolve, reject);
            } catch (e) {
              reject(e);
            }
          }, 0)
        });
      }
    })
    return promise2;
  }
resolvePromise方法的实现
const resolvePromise = (x, promise2, resolve, reject) => {
  if (x === promise2) {
    return reject(new TypeError("then回调的返回值和它本身相等,陷入死循环"))
  }
  if ((typeof x === "object" && x !== null) || typeof x === "function") {

    try {
      let then = x.then;
      if (typeof then === "function") {// 如果x对象或方法中的then属性也是一个方法,就继续执行这个方法
        then.call(x, y => {
          resolvePromise(y, promise2, resolve, reject);
        }, err => {
          reject(err);
        })
      } else { // 对象或者函数中没有 then 方法,就按照普通值处理
        resolve(x);
      }
    } catch (e) {
      reject(e);
    }
  } else {
    resolve(x); // x 不是对象或方法,是一个普通值
  }
}

测试
    // 下面都是测试 
  let promise = new MyPromise(function (reslove, reject) {
    if (true) {
      reslove("resolve函数传递的数据");// 如果执行reslove函数,那么Promise对象将从Pending状态转换为Resolved状态
    } else {
      reject("reject函数传递的数据");// 如果执行reslove函数,那么Promise对象将从Pending状态转换为Rejected状态
    }
  })
  // console.log(promise);
  promise.then(function (data) {
    console.log(data + "  Resolved状态的回调函数执行了");
  }, function (data) {
    console.log(data + "  Reject状态的回调执行了");
  }).then(function () {
    console.log("另一个then函数");
  })

//输出:
//resolved执行了
//resolve函数传递的数据  Resolved状态的回调函数执行了
//resolved执行了
//另一个then函数
//resolved执行了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值