手写Promise

const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

//创建微队列
function runMicroTask(callback) {
  //判断node环境 process.nextTick是node的微队列
  if (process && process.nextTick) {
    process.nextTick(callback); //node环境的微队列
  } else if (MutationObserver) {
    //MutationObserver 浏览器微队列
    const p = document.createElement("p"); //创建p标签
    const observer = new MutationObserver(callback); //放入微队列
    observer.observe(p, {
      childList: true, //观察内部发送的变化
    });
    p.innerHTML = "1";
  } else {
    setTimeout(callback, 0); //等待0秒好执行
  }
}

//判断一个数据是否是Promise对象
function isPromise(obj) {
  return !!(obj && typeof obj === "object" && typeof obj.then === "function");
}

class MyPromise {
  constructor(executor) {
    this._state = PENDING; //状态
    this._value = undefined; //数据
    this._handlers = []; //处理函数的队列
    try {
      executor(this._resolve.bind(this), this._reject.bind(this)); //成功
    } catch (error) {
      this.reject(error); //失败
    }
  }

  /*
    向处理函数中添加一个函数,executor 添加的函数 state 状态  ,resolve then返回的promise成功 reject 让then返回的promise失败
    目的是:要是想要让then执行,那么一定是有成功/失败的状态下才会去执行then,所以这时候then就会进入微队列等待状态的完成!所以需要给then编写一个微队列
    但是这时候遇到一个问题:添加到微队列后,他也不知道任务的状态是成功的还是失败的,所以需要编写_pushHandlers的方法

      executor: [Function: A1],
      state: 'fulfilled',
      resolve: [Function: bound _resolve],
      reject: [Function: bound _reject]
  */
  _pushHandlers(executor, state, resolve, reject) {
    this._handlers.push({
      executor,
      state,
      resolve,
      reject,
    });
  }

  /*
    根据实际清空,执行队列
  */
  _runHandlers() {
    if (this._state === PENDING) {
      //目前任务还是挂起
      return;
    }

    //执行一个队列,删除一个队列
    while (this._handlers[0]) {
      const handler = this._handlers[0];
      this._runHandler(handler);
      this._handlers.shift();
    }
  }

  //  处理一个handlers
  _runHandler({ executor, state, resolve, reject }) {
    //放入微队列
    runMicroTask(() => {
      if (this._state !== state) {
        //当前状态如果为失败= rejected !== 微服务里面的state进行比较  不等于则不加入微队列
        //状态不一致,不处理,不加入微队列
        return;
      }
      //不是函数的情况
      if (typeof executor !== "function") {
        //三目运算符:当this._state=通过,则执行resolve(值),否则执行reject(值)
        this._state === FULFILLED ? resolve(this._value) : reject(this._value);
        return;
      }
      try {
        const result = executor(this._value); //将微队列的executor的函数名进行赋值
        if (isPromise(result)) {
          result.then(resolve, reject);
        } else {
          resolve(result);
        }
      } catch (error) {
        reject(error);
      }
      //console.log(this._state)
      // console.log(handler,'测试')
    });
  }

  then(onFulfilled, onRejected) {
    return new MyPromise((resolve, reject) => {
      // 将then里面的数据放到微队列,等待状态完成后执行
      this._pushHandlers(onFulfilled, FULFILLED, resolve, reject); //成功的
      this._pushHandlers(onRejected, REJECTED, resolve, reject); //失败的
      this._runHandlers(); //重新执行队列
    });
  }
  //处理失败的场景
  catch(onRejected) {
    return this.then(null, onRejected);
  }
  //无论失败还是成功都会执行该函数
  finally(onSettled) {
    return this.then(
      (data) => {
        onSettled();
        return data;
      },
      (reason) => {
        onSettled();
        return reason;
      }
    );
  }

  _changeState(newState, value) {
    if (this._state != PENDING) {
      //要是当前start不是挂起状态,说明已经执行了,那么就return,不在执行
      return;
    }
    this._state = newState;
    this._value = value;
    this._runHandlers(); //重新执行
  }

  // 成功的方法
  _resolve(data) {
    //状态和值
    this._changeState(FULFILLED, data);
  }
  //失败的方法
  _reject(fail) {
    this._changeState(REJECTED, fail);
  }

  /* 返回已完成的promise;特殊情况:
  1.传递的data本身就是es6的promise对象
  2.传递的data是promiseLike(promise A+规范),返回新的promise,状态和其保持一致
  */
  //成功的  编写静态的
  static resolve(data) {
    if (data instanceof MyPromise) {
      return data;
    }
    return new MyPromise((resolve, reject) => {
      if (isPromise(data)) {
        data.then(resolve, reject);
      } else {
        resolve(data);
      }
    });
  }

  //失败的 编写静态
  static reject(reason) {
    return new MyPromise((resolve, reject) => {
      reject(reason);
    });
  }

  /*
    Promise迭代器,包含多个Promise
    全部Promise成功,则返回Promise成功,数据为所有Promise成功的数据,并且顺序是按照传入的顺序排列
    只要有一个Promise失败,则返回的Promise失败,原因是第一个失败的Promise的原因
 
  */
  static all(proms) {
    return new MyPromise((resolve, reject) => {
      try {
        const result = [];
        let count = 0; //promise总数
        let fulfilledCount = 0; //已完成的数量
        for (const p of proms) {
          let i = count;
          count++;
          MyPromise.resolve(p).then((data) => {
            fulfilledCount++;
            result[i] = data;
            if (fulfilledCount === count) {
              //当前最后一个Promise完成
              resolve(result);
            }
          }, reject);
        }
        if (count === 0) {
          resolve(result);
        }
      } catch (error) {
        reject(error);
      }
    });
  }


    /*
        等待所有promise有结果之后
        该方法返回的promise完成
        并且按照顺序将所有结果汇总
    */
 static allSettled(proms){
     const ps = [];
     for(const p of proms){
        ps.push(
            MyPromise.resolve(p).then(
                (value) =>({
                    status:FULFILLED,
                    value
                }),
                (reason)=>({
                    status:REJECTED,
                    reason
                })
            )
        )
     }
     return MyPromise.all(ps)
 }

 //返回的Promise与第一个有结果的一致
 static race(proms){
    return new MyPromise((resolve,reject)=>{
        for(const p  of proms){
            MyPromise.resolve(p).then(resolve,reject)
        }
    })
 }

}

//两个参数,在class类里面使用该参数
const pro = new MyPromise((resolve, reject) => {
 setTimeout(()=>{
    reject(1);
 },1)
});

//互操作 自己写的Promise 和官方写的promise可以互相操作
// pro
// .then((data)=>{
//     console.log(data);//1
//     return new Promise((resolve)=>{
//         resolve(2)
//     })
// })
// .then((data)=>{
//     console.log(data);//2
// })

// const pro2 = pro.finally((d)=>{
//     console.log('finally',d);
//     throw 123
// })
// setTimeout(()=>console.log(pro2))

// MyPromise.all([pro]).then(
//   (data) => {
//     console.log("成功", data);
//   },
//   (reason) => {
//     console.log("失败", reason);
//   }
// );

// const pro1 = MyPromise.allSettled([
//     pro,
//     MyPromise.resolve(2),
//     MyPromise.resolve(3),
//     MyPromise.resolve(4),
//     5
// ])
// pro1.then((result)=>{
//     console.log(result)
// })

const pro2 = new MyPromise((resolve, reject) => {
    setTimeout(()=>{
       resolve(1);
    },10)
   });

const pro1 = MyPromise.race([pro,pro2]);
pro1.then(
    (data)=>{
        console.log('成功',data)
    },
    (reason)=>{
        console.log('失败',reason)
    }
    )
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

//创建微队列
function runMicroTask(callback) {
  //判断node环境 process.nextTick是node的微队列
  if (process && process.nextTick) {
    process.nextTick(callback); //node环境的微队列
  } else if (MutationObserver) {
    //MutationObserver 浏览器微队列
    const p = document.createElement("p"); //创建p标签
    const observer = new MutationObserver(callback); //放入微队列
    observer.observe(p, {
      childList: true, //观察内部发送的变化
    });
    p.innerHTML = "1";
  } else {
    setTimeout(callback, 0); //等待0秒好执行
  }
}

//判断一个数据是否是Promise对象
function isPromise(obj) {
  return !!(obj && typeof obj === "object" && typeof obj.then === "function");
}

class MyPromise {
  constructor(executor) {
    this._state = PENDING; //状态
    this._value = undefined; //数据
    this._handlers = []; //处理函数的队列
    try {
      executor(this._resolve.bind(this), this._reject.bind(this)); //成功
    } catch (error) {
      this.reject(error); //失败
    }
  }

  /*
    向处理函数中添加一个函数,executor 添加的函数 state 状态  ,resolve then返回的promise成功 reject 让then返回的promise失败
    目的是:要是想要让then执行,那么一定是有成功/失败的状态下才会去执行then,所以这时候then就会进入微队列等待状态的完成!所以需要给then编写一个微队列
    但是这时候遇到一个问题:添加到微队列后,他也不知道任务的状态是成功的还是失败的,所以需要编写_pushHandlers的方法

      executor: [Function: A1],
      state: 'fulfilled',
      resolve: [Function: bound _resolve],
      reject: [Function: bound _reject]
  */
  _pushHandlers(executor, state, resolve, reject) {
    this._handlers.push({
      executor,
      state,
      resolve,
      reject,
    });
  }

  /*
    根据实际清空,执行队列
  */
  _runHandlers() {
    if (this._state === PENDING) {
      //目前任务还是挂起
      return;
    }

    //执行一个队列,删除一个队列
    while (this._handlers[0]) {
      const handler = this._handlers[0];
      this._runHandler(handler);
      this._handlers.shift();
    }
  }

  //  处理一个handlers
  _runHandler({ executor, state, resolve, reject }) {
    //放入微队列
    runMicroTask(() => {
      if (this._state !== state) {
        //当前状态如果为失败= rejected !== 微服务里面的state进行比较  不等于则不加入微队列
        //状态不一致,不处理,不加入微队列
        return;
      }
      //不是函数的情况
      if (typeof executor !== "function") {
        //三目运算符:当this._state=通过,则执行resolve(值),否则执行reject(值)
        this._state === FULFILLED ? resolve(this._value) : reject(this._value);
        return;
      }
      try {
        const result = executor(this._value); //将微队列的executor的函数名进行赋值
        if (isPromise(result)) {
          result.then(resolve, reject);
        } else {
          resolve(result);
        }
      } catch (error) {
        reject(error);
      }
      //console.log(this._state)
      // console.log(handler,'测试')
    });
  }

  then(onFulfilled, onRejected) {
    return new MyPromise((resolve, reject) => {
      // 将then里面的数据放到微队列,等待状态完成后执行
      this._pushHandlers(onFulfilled, FULFILLED, resolve, reject); //成功的
      this._pushHandlers(onRejected, REJECTED, resolve, reject); //失败的
      this._runHandlers(); //重新执行队列
    });
  }
  //处理失败的场景
  catch(onRejected) {
    return this.then(null, onRejected);
  }
  //无论失败还是成功都会执行该函数
  finally(onSettled) {
    return this.then(
      (data) => {
        onSettled();
        return data;
      },
      (reason) => {
        onSettled();
        return reason;
      }
    );
  }

  _changeState(newState, value) {
    if (this._state != PENDING) {
      //要是当前start不是挂起状态,说明已经执行了,那么就return,不在执行
      return;
    }
    this._state = newState;
    this._value = value;
    this._runHandlers(); //重新执行
  }

  // 成功的方法
  _resolve(data) {
    //状态和值
    this._changeState(FULFILLED, data);
  }
  //失败的方法
  _reject(fail) {
    this._changeState(REJECTED, fail);
  }

  /* 返回已完成的promise;特殊情况:
  1.传递的data本身就是es6的promise对象
  2.传递的data是promiseLike(promise A+规范),返回新的promise,状态和其保持一致
  */
  //成功的  编写静态的
  static resolve(data) {
    if (data instanceof MyPromise) {
      return data;
    }
    return new MyPromise((resolve, reject) => {
      if (isPromise(data)) {
        data.then(resolve, reject);
      } else {
        resolve(data);
      }
    });
  }

  //失败的 编写静态
  static reject(reason) {
    return new MyPromise((resolve, reject) => {
      reject(reason);
    });
  }

  /*
    Promise迭代器,包含多个Promise
    全部Promise成功,则返回Promise成功,数据为所有Promise成功的数据,并且顺序是按照传入的顺序排列
    只要有一个Promise失败,则返回的Promise失败,原因是第一个失败的Promise的原因
 
  */
  static all(proms) {
    return new MyPromise((resolve, reject) => {
      try {
        const result = [];
        let count = 0; //promise总数
        let fulfilledCount = 0; //已完成的数量
        for (const p of proms) {
          let i = count;
          count++;
          MyPromise.resolve(p).then((data) => {
            fulfilledCount++;
            result[i] = data;
            if (fulfilledCount === count) {
              //当前最后一个Promise完成
              resolve(result);
            }
          }, reject);
        }
        if (count === 0) {
          resolve(result);
        }
      } catch (error) {
        reject(error);
      }
    });
  }


    /*
        等待所有promise有结果之后
        该方法返回的promise完成
        并且按照顺序将所有结果汇总
    */
 static allSettled(proms){
     const ps = [];
     for(const p of proms){
        ps.push(
            MyPromise.resolve(p).then(
                (value) =>({
                    status:FULFILLED,
                    value
                }),
                (reason)=>({
                    status:REJECTED,
                    reason
                })
            )
        )
     }
     return MyPromise.all(ps)
 }

 //返回的Promise与第一个有结果的一致
 static race(proms){
    return new MyPromise((resolve,reject)=>{
        for(const p  of proms){
            MyPromise.resolve(p).then(resolve,reject)
        }
    })
 }

}

//两个参数,在class类里面使用该参数
const pro = new MyPromise((resolve, reject) => {
 setTimeout(()=>{
    reject(1);
 },1)
});

//互操作 自己写的Promise 和官方写的promise可以互相操作
// pro
// .then((data)=>{
//     console.log(data);//1
//     return new Promise((resolve)=>{
//         resolve(2)
//     })
// })
// .then((data)=>{
//     console.log(data);//2
// })

// const pro2 = pro.finally((d)=>{
//     console.log('finally',d);
//     throw 123
// })
// setTimeout(()=>console.log(pro2))

// MyPromise.all([pro]).then(
//   (data) => {
//     console.log("成功", data);
//   },
//   (reason) => {
//     console.log("失败", reason);
//   }
// );

// const pro1 = MyPromise.allSettled([
//     pro,
//     MyPromise.resolve(2),
//     MyPromise.resolve(3),
//     MyPromise.resolve(4),
//     5
// ])
// pro1.then((result)=>{
//     console.log(result)
// })

const pro2 = new MyPromise((resolve, reject) => {
    setTimeout(()=>{
       resolve(1);
    },10)
   });

const pro1 = MyPromise.race([pro,pro2]);
pro1.then(
    (data)=>{
        console.log('成功',data)
    },
    (reason)=>{
        console.log('失败',reason)
    }
    )

posted on 2023-05-11 17:55  爱前端的小魏  阅读(26)  评论(0编辑  收藏  举报

导航