手写简易版的promise

1.promise的基本概念

Promise是一种抽象异步处理对象,Promise类的构造函数中使用一个参数,参数值为一个回调函数。该回调函数又使用两个参数,参数值分别为两个回调函数(resolve,reject),如果执行成功则调用resolve回调函数,否则执行reject回调函数

如下代码,promise是一个类,所有我们可以用构造函数来进行实现,promise中可以传入一个参数,参数值为一个函数((resolve,reject) => {}),其参数值又可以传入两个参数,参数值为resolve和reject函数,则我们实现的promise需要接收一个参数,其参数为立即执行函数,并实现两个参数(resolve和reject), 因promise从初状态pending跳转到另一个状态后,就不可改变,所以用status存放状态,在resolve和reject实现函数中,每次都加个判断,只有是初状态pending才会执行

let that; 
function Promise(executor) {
  
  that = this;
  this.status = "pending";   // 保存promise中的状态,最初为pending
  this.success = undefined;  // 存成功状态传入的值
  this.err = undefined; // 存失败状态传入的值
  // 以下两个数组是 当new Promise对象时,成功(resolve) 或者失败(reject) 存放在异步操作,
  // 例如(放在定时器中),需要先把.then(回调函数) 先存放在数组内,
  this.resolveArray = [];
  this.rejectArray = [];
  let resolve = val => {
    setTimeout(() => {
      if (this.status === "pending") {
          this.status = "fulfilled";
          this.success = val;
            // 遍历数组是为了查看promise对象中是否有异步操作
          this.resolveArray.forEach(value => {
            value();
          })
      }
    })

  }
  let reject = val => {
    setTimeout(() => {
      if (this.status === "pending") {
        this.status = "rejected";
        this.err = val;
        // 遍历数组是为了查看promise对象中是否有异步操作
        this.rejectArray.forEach(value => {
          value();
        })
      }
    })

  }
  // 若new promise 中throw出错误,则执行catch里面
  try {
    executor(resolve, reject);
  } catch (e) {
    reject(e);
  }

}

接下来将.then函数挂载到promise的原型链上,代码如下

Promise.prototype.then = (resolve, reject) => {
  let res = undefined;
  
  if (that.status === "fulfilled") {
     resolve(that.success);
  }
  if (that.status === "rejected") {

      res = reject(that.err);    
  }
  // 没有走成功或失败的回调函数  以下是因为代码中有异步操作,所以状态还是pending
  if (that.status === "pending") {
    that.resolveArray.push(() => {
      resolve(that.success);
    });
    that.rejectArray.push(() => {
        res = reject(that.err);
    });
  }

}

接下来实现创建promise类中有无定时器的实行结果

//promise类中无定时器
let p = new Promise((resolve, reject) => {
  resolve("success");
})
p.then(data => {
  console.log(data);
}, err => {
  console.log(err);
})

运行结果如下:

 

// promise中有定时器
let p = new Promise((resolve, reject) => {
  setTimeout(() => {

      resolve('success');
      console.log("666");
  }, 1000)
})
p.then(data => {
  console.log(data);
}, err => {
  console.log(err);
})

运行结果如下:

 说明:在定时器中因 console是同步任务,所以是先输出666,再输出success,这也是我们前面在resolve和reject函数中加入定时器的原因,将其置于宏任务中

实现promise的then的链式,即在每个执行完的回调函数中再返回promise对象,默认是返回成功的状态,代码如下:

// 将then函数修改如下
Promise.prototype.then = (resolve, reject) => {
  let res = undefined; // res为保存上一步then返回的值
  let flag = 0;   // 当flag为0 时,表示返回成功的回调函数,1表示返回失败的回调函数
  if (that.status === "fulfilled") {
    try {
      res = resolve(that.success);

    } catch (e) {
      flag = 1;
      res = e;
    }
  }
  if (that.status === "rejected") {

    try {
      res = reject(that.err);
    } catch (e) {
      flag = 1;
      res = e;
    }

  }
  // 没有走成功或失败的回调函数
  if (that.status === "pending") {
    that.resolveArray.push(() => {
      try {
        res = resolve(that.success);
      } catch (e) {
        flag = 1;
        res = e;
      }
    });
    that.rejectArray.push(() => {
      try {
        res = reject(that.err);
      } catch (e) {
        flag = 1;
        res = e;
      }
    });
  }
    // 判断上一步返回的是否为promise对象,若是直接返回,如果不是,则创建一个promise对象
  if(isPromise(res)){
      return res;
    }
  return new Promise((resolve,reject) => {
      
        if(flag){
          reject(res);
        }else{
          resolve(res);
        }
    })


}

接下来将创建一个链式的then,代码如下

let p = new Promise((resolve, reject) => {
  resolve("success");
})
p.then(data => {
  console.log(data);
}, err => {
  console.log(err);
}).then(data => {
  console.log(data);
})

运行结果如下:

说明:因上一步then没有返回值,则默认返回undefined,所以结果打印出 success和undefined 

catch的实现,代码如下

// catch为失败的回调函数
Promise.prototype.catch = (reject) => {
  return that.then(undefined,reject);
}
let p = new Promise((resolve, reject) => {
 
  reject("success");
})
p.catch(err => {
  console.log(err + " err");
})

运行结果如下:

 以上为简易的promise实现,还有一些不足之处,后续会再改正!!!!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很高兴为您提供一个手写Promise 实现,代码如下: class Promise { constructor(executor) { this.state = 'pending'; this.value = undefined; this.reason = undefined; this.onResolvedCallbacks = []; this.onRejectedCallbacks = []; const resolve = (value) => { if (this.state === 'pending') { this.state = 'fulfilled'; this.value = value; this.onResolvedCallbacks.forEach((fn) => fn()); } }; const reject = (reason) => { if (this.state === 'pending') { this.state = 'rejected'; this.reason = reason; this.onRejectedCallbacks.forEach((fn) => fn()); } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value; onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason }; const promise2 = new Promise((resolve, reject) => { if (this.state === 'fulfilled') { setTimeout(() => { try { const x = onFulfilled(this.value); Promise.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } if (this.state === 'rejected') { setTimeout(() => { try { const x = onRejected(this.reason); Promise.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } if (this.state === 'pending') { this.onResolvedCallbacks.push(() => { setTimeout(() => { try { const x = onFulfilled(this.value); Promise.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try { const x = onRejected(this.reason); Promise.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); } }); return promise2; } static resolvePromise(promise2, x, resolve, reject) { if (promise2 === x) { return reject(new TypeError('Chaining cycle detected for promise')); } let called = false; if (x instanceof Promise) { x.then((value) => { Promise.resolvePromise(promise2, value, resolve, reject); }, reject); } else if (x !== null && (typeof x === 'object' || typeof x === 'function')) { try { const then = x.then; if (typeof then === 'function') { then.call(x, (value) => { if (called) return; called = true; Promise.resolvePromise(promise2, value, resolve, reject); }, (reason) => { if (called) return; called = true; reject(reason); }); } else { resolve(x); } } catch (error) { if (called) return; called = true; reject(error); } } else { resolve(x); } } }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值