Promise 源码

一、Promise 类核心逻辑实现

1.Promise 逻辑分析

  • Promise 就是一个类 在执行这个类的时候 需要传递一个执行器进去 执行器会立即执行
  • Promise 中有三种状态 分别是 成功 fulfilled 、失败 rejected 、 pending
    • pending => fulfilled
    • pending => rejected
    • 一旦状态确定就不可更改
  • resolve 和 reject 函数是用来更改状态的
    • resolve : fulfilled
    • reject : rejected
  • then 方法内部就是判断 promise 内部状态,如果是成功,就调用成功回调函数,如果是失败,就调用失败回调函数
    • then 方法是被定义在原型对象中的

2.Promise 逻辑分析代码实现

// Mypromise.js     
const PENDING = 'pending';   // 等待
const FULFILLED = 'fulfilled';    // 成功
const REJECTED = 'rejected';      // 失败


class MyPromise {
  constructor (executor) {
    executor(this.resolve, this.reject);
  }
  // promise 状态
  status = PENDING;
  // promise 成功之后的值
  value = undefined;
  reason = undefined;
  // promise 失败后的原因
  resolve = value => {
    // 如果状态不是等待 组织程序向下执行
    if (this.status != PENDING) return;
    // 将状态更改为成功
    this.status = FULFILLED;
    // 保存成功之后的值
    this.value = value;
  }
  reject = reason => {
    // 如果状态不是等待 组织程序向下执行
    if (this.status != PENDING) return;
    // 将状态更改为失败
    this.status = REJECTED;
    // 保存失败后的原因
    this.reason = reason;
  }
  then(successCallback, failCallback){
    // 判断状态
    if (this.status === FULFILLED) {
      successCallback(this.value);
    } else if (this.status === REJECTED) {
      failCallback(this.reason);
    }
  }
}
module.exports = MyPromise;
// index.js
let MyPromise = require('./myPromise');
let promise  = new MyPromise ( (resolve, reject) => {
  resolve('成功');
  reject('失败');
} ) 

promise.then( value => {
  console.log(value);
}, reason => {
  console.log(reason);
} )

2.在 Promise 中加入异步逻辑

  • 当给 Promise 中的立即执行函数是异步的时候,我们在给 .then 原型方法中就要把传递的两个成功和失败的回调函数给保存在 Promise 这个类的变量中。等待立即执行函数的异步代码调用。
// Mypromise.js 
const PENDING = 'pending';   // 等待
const FULFILLED = 'fulfilled';    // 成功
const REJECTED = 'rejected';      // 失败


class MyPromise {
  // promise 状态
  status = PENDING;
  // promise 成功之后的值
  value = undefined;
   // promise 失败后的原因
  reason = undefined;
  // 用来保存 .then 中成功的回调函数
  successCallback = undefined;
  // 用来保存 .then 中失败的回调函数
  failCallback = undefined;

  constructor (executor) {
    executor(this.resolve, this.reject);
  }
  resolve = value => {
    // 如果状态不是等待 组织程序向下执行
    if (this.status != PENDING) return;
    // 将状态更改为成功
    this.status = FULFILLED;
    // 保存成功之后的值
    this.value = value; 
     // 判断 成功回调函数 successCallback 是否存在 如果存在就去调用它并给参数值
     this.successCallback && this.successCallback(value)   
  }
  reject = reason => {
    // 如果状态不是等待 组织程序向下执行
    if (this.status != PENDING) return;
    // 将状态更改为失败
    this.status = REJECTED;
    // 保存失败后的原因
    this.reason = reason;
   // 判断 失败回调函数 successCallback 是否存在 如果存在就去调用它并给参数值
   this.failCallback && this.failCallback(reason);   
  }
  then(successCallback, failCallback){
    // 判断状态
    if (this.status === FULFILLED) {
      successCallback(this.value);
    } else if (this.status === REJECTED) {
      failCallback(this.reason);
    }else {
      this.successCallback = successCallback;
      this.failCallback = failCallback;
    }
  }
}
module.exports = MyPromise;		// commonJs的导出语法 因为是在nodejs红中调用的。
// index.js
let MyPromise = require('./myPromise');		// commonJs的导出、入语法 因为是在nodejs中调用的。
let promise  = new MyPromise ( (resolve, reject) => {
  setTimeout(() => {
    resolve('成功');  
    // reject('失败');
  }, 2000);
} ) 

promise.then( value => {
  console.log(value);
}, reason => {
  console.log(reason);
} )

3.实现 .then 方法 多次调用添加多个回调函数

  • 在 Promise 中多次调用 then 方法时我们应该把 then 方法中传递过来的方法用数组保存起来,然后在执行回调的时候用数组弹出栈的方法取出并调用该方法 shift()
// myPromise.js
const PENDING = 'pending';   // 等待
const FULFILLED = 'fulfilled';    // 成功
const REJECTED = 'rejected';      // 失败


class MyPromise {
  // promise 状态
  status = PENDING;
  // promise 成功之后的值
  value = undefined;
   // promise 失败后的原因
  reason = undefined;
  // 用来保存 .then 中成功的回调函数
  successCallback = [];
  // 用来保存 .then 中失败的回调函数
  failCallback = []

  constructor (executor) {
    executor(this.resolve, this.reject);
  }
  resolve = value => {
    // 如果状态不是等待 组织程序向下执行
    if (this.status != PENDING) return;
    // 将状态更改为成功
    this.status = FULFILLED;
    // 保存成功之后的值
    this.value = value; 
     // 判断 成功回调函数 successCallback 是否存在 如果存在就去调用它并给参数值
    //  this.successCallback && this.successCallback(value)  
    while (this.successCallback.length) this.successCallback.shift()(value)
  }
  reject = reason => {
    // 如果状态不是等待 组织程序向下执行
    if (this.status != PENDING) return;
    // 将状态更改为失败
    this.status = REJECTED;
    // 保存失败后的原因
    this.reason = reason;
   // 判断 失败回调函数 successCallback 是否存在 如果存在就去调用它并给参数值
  //  this.failCallback && this.failCallback(reason); 
  while (this.failCallback.length) this.failCallback.shift()(reason);  
  }
  then(successCallback, failCallback){
    // 判断状态
    if (this.status === FULFILLED) {
      successCallback(this.value);
    } else if (this.status === REJECTED) {
      failCallback(this.reason);
    }else {
      this.successCallback.push(successCallback);		// 添加多次调用 then 的成功方法
      this.failCallback.push(failCallback);				// 添加多次调用 then 的失败方法
    }
  }
}
module.exports = MyPromise;
// index.js 中多次调用then方法
let MyPromise = require('./myPromise');
let promise  = new MyPromise ( (resolve, reject) => {
  setTimeout(() => {
    resolve('成功  .........');  
    // reject('失败');
  }, 2000);
} ) 

promise.then( value => {
  console.log(1);
  console.log(value);
}, reason => {
  console.log(reason);
} )
promise.then( value => {
  console.log(2);
  console.log(value);
}, reason => {
  console.log(reason);
} )
promise.then( value => {
  console.log(3);
  console.log(value);
}, reason => {
  console.log(reason);
} )

4. then 方法的链式调用

then 链式调用(上)

promise.then(value => {
  console.log(value);
}).then( value => {
  console.log(value);
})
  1. 在链式调用第一个 then 方法的时候 应该返回 一个 Promise 并且立即执行当前 中的方法 , 好让下次继续链式调用
  2. 返回 Promise 的时候应当记录当前上一个 then 方法返回的参数
// myPromise.js
const PENDING = 'pending';   // 等待
const FULFILLED = 'fulfilled';    // 成功
const REJECTED = 'rejected';      // 失败


class MyPromise {
  // promise 状态
  status = PENDING;
  // promise 成功之后的值
  value = undefined;
   // promise 失败后的原因
  reason = undefined;
  // 用来保存 .then 中成功的回调函数
  successCallback = [];
  // 用来保存 .then 中失败的回调函数
  failCallback = []

  constructor (executor) {
    executor(this.resolve, this.reject);
  }
  resolve = value => {
    // 如果状态不是等待 组织程序向下执行
    if (this.status != PENDING) return;
    // 将状态更改为成功
    this.status = FULFILLED;
    // 保存成功之后的值
    this.value = value; 
     // 判断 成功回调函数 successCallback 是否存在 如果存在就去调用它并给参数值
    //  this.successCallback && this.successCallback(value)  
    while (this.successCallback.length) this.successCallback.shift()(value)
  }
  reject = reason => {
    // 如果状态不是等待 组织程序向下执行
    if (this.status != PENDING) return;
    // 将状态更改为失败
    this.status = REJECTED;
    // 保存失败后的原因
    this.reason = reason;
   // 判断 失败回调函数 successCallback 是否存在 如果存在就去调用它并给参数值
  //  this.failCallback && this.failCallback(reason); 
  while (this.failCallback.length) this.failCallback.shift()(reason);  
  }
  then(successCallback, failCallback){
    let promise2 = new Promise((resolve, reject) => {
      // 判断状态
      if (this.status === FULFILLED) {
        let x= successCallback(this.value);
        return resolve(x)
      } else if (this.status === REJECTED) {
        let y = failCallback(this.reason);
        return reject(y)
      }else {
        this.successCallback.push(successCallback);
        this.failCallback.push(failCallback);
      }
    })
    return promise2
  }
}
module.exports = MyPromise;
// index.js
let MyPromise = require('./myPromise');
let promise  = new MyPromise ( (resolve, reject) => {
  // setTimeout(() => {
    resolve('成功  .........');  
    // reject('失败');
  // }, 2000);
} ) 

promise.then( value => {
  console.log(value);
  return 100
}).then( value => {
  console.log(value);
})

then 链式调用(下)

  1. 判断额 x 的值是普通对象还是 promise 对象
  2. ​ 如果是普通值 直接调用 resolve
  3. ​ 如果是 promise 对象 查看promisee 对象返回的结果
  4. ​ 再根据 promise 对象返回的结果 决定调用resolve 还是调用reject
// myPromise.js
const PENDING = 'pending';   // 等待
const FULFILLED = 'fulfilled';    // 成功
const REJECTED = 'rejected';      // 失败


class MyPromise {
  // promise 状态
  status = PENDING;
  // promise 成功之后的值
  value = undefined;
   // promise 失败后的原因
  reason = undefined;
  // 用来保存 .then 中成功的回调函数
  successCallback = [];
  // 用来保存 .then 中失败的回调函数
  failCallback = []

  constructor (executor) {
    executor(this.resolve, this.reject);
  }
  resolve = value => {
    // 如果状态不是等待 组织程序向下执行
    if (this.status != PENDING) return;
    // 将状态更改为成功
    this.status = FULFILLED;
    // 保存成功之后的值
    this.value = value; 
     // 判断 成功回调函数 successCallback 是否存在 如果存在就去调用它并给参数值
    //  this.successCallback && this.successCallback(value)  
    while (this.successCallback.length) this.successCallback.shift()(value)
  }
  reject = reason => {
    // 如果状态不是等待 组织程序向下执行
    if (this.status != PENDING) return;
    // 将状态更改为失败
    this.status = REJECTED;
    // 保存失败后的原因
    this.reason = reason;
   // 判断 失败回调函数 successCallback 是否存在 如果存在就去调用它并给参数值
  //  this.failCallback && this.failCallback(reason); 
  while (this.failCallback.length) this.failCallback.shift()(reason);  
  }
  then(successCallback, failCallback){
    let promise2 = new Promise((resolve, reject) => {
      // 判断状态
      if (this.status === FULFILLED) {
        // 判断额 x 的值是普通对象还是 promise 对象
        // 如果是普通值 直接调用 resolve
        // 如果是 promise 对象 查看promisee 对象返回的结果
        // 再根据 promise 对象返回的结果 决定调用resolve 还是调用reject
        let x= successCallback(this.value);
        resolvePromise ( x, resolve, reject);
        // return resolve(x)
      } else if (this.status === REJECTED) {
        let y = failCallback(this.reason);
        return reject(y)
      }else {
        this.successCallback.push(successCallback);
        this.failCallback.push(failCallback);
      }
    })
    return promise2
  }
}

function resolvePromise ( x, resolve, reject) {
  if ( x instanceof MyPromise) {
    // promise 对象
    // x.then(value => resolve(value), reason => reject(reason));
    x.then(resolve, reject)
  } else {
    // 普通值
    resolve(x);
  }
}
module.exports = MyPromise;
// index.js
let MyPromise = require('./myPromise');
let promise  = new MyPromise ( (resolve, reject) => {
  // setTimeout(() => {
    resolve('成功  .........');  
    // reject('失败');
  // }, 2000);
} ) 

function other() {
  return new MyPromise((resolve, reject) => {
    resolve('other');
  } )
}

promise.then( value => {
  console.log(value);
  return other()
}).then( value => {
  console.log(value);
})

5.then 方法链式调用识别 Promise 对象自返回

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值