手写简易版的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实现,还有一些不足之处,后续会再改正!!!!!!

你可能感兴趣的:(javascript,前端,css,html,css3)