其他分享
首页 > 其他分享> > Promise详解二(解读Promise规范+手写Promise)

Promise详解二(解读Promise规范+手写Promise)

作者:互联网

任何符合promise规范的对象和函数都可以成为Promise。
以下内容参考自promise A plus 规范,地址:https://promisesaplus.com/

基本术语

  1. Promise:是一个具有then方法的对象或函数,其行为符合Promises/A+规范。
  2. thenadble:是一个定义了then方法的对象或函数。
  3. value:指任何JavaScript的合法值(包括undefined,thenable,和promise)。
  4. exception:使用throw抛出的一个值。
  5. reason:说明Promise状态改为rejected的原因。

要求

1. Promise的状态

一个Promise的当前状态必须是一下三种状态中的一种:pending,fullfilled,rejected。

2. then方法

Promise必须提供一个then方法,可以查看其当前或最终的值或者原因。
Promise的then方法接收两个可选参数:Promise.then(onFullfilled, onRejected)。

2.1 如果onFullfilled或onRejected不是函数,则需要忽略他们。
2.2 如果onFullfilled是一个函数:

2.3 如果onRejected是一个函数:

2.4 当执行上下文堆栈仅包含“platform code”之前,不能调用onFullFilled和onRejected。

这里“platform code”是指引擎、环境和Promise参数函数代码。在实际应用中,这一要求确保onFulfilled和onRejected在调用事件循环后以新的堆栈异步执行。这可以通过“宏任务”机制(如setTimeout或setImmediate)实现,也可以通过“微任务”机制(如MutationObserver或process.nextTick实现。

2.5 onFulfilled 和 onRejected 必须被作为普通函数调⽤(即⾮实例化调⽤,这样函数内部 this ⾮严格模式下指向 window)。
2.6 then ⽅法可以被同⼀个 promise 调⽤多次。

2.7 then ⽅法必须返回⼀个新的 promise 对象: promise2 = promise1.then(onFulfilled, onRejected);

3. Promise的解析过程

promise解析过程是一个抽象操作,输入一个promise和一个值,我们将其表示为[[Resolve]](promise,x)。如果x是一个tenable,它试图使promise采用x的状态。否则,它就将x值包装成一个Promise。
3.1 如果promise和x指向同一个对象,Promise将进入rejected状态,并返回一个TypeError作为拒绝原因。
3.2 如果 x 为 promise:

3.3 如果 x 为对象或函数(不常见):

3.4 如果 x 不是对象或者函数,以x为参数将Promise变为fullfilled状态(重要且常见)。

------------------------------------------------------------手写Promise来啦---------------------------------------------------------------
------------------------------------------------------------手写Promise来袭---------------------------------------------------------------

class MyPromise {
  constructor(handleFn) {
    // Promise的状态
    this.PromiseState = "pending";
    // Promise的结果
    this.PromiseValue = null;

    // 画重点!!!这两个list是为了将下一个Promise与当前Promise相关联
    this._toNextResolve = [];
    this._toNextReject = [];
    // Promise接收的函数参数
    handleFn(this.triggerResolve.bind(this), this.triggerReject.bind(this));
  }

  // resolve处理
  triggerResolve(data) {
    // 这里使用setTimeout的原因是:确保resolve处理函数在handleFn所处的事件循环后以新的堆栈异步执行。(参见:2.4)
    setTimeout(() => {
      // Promise的状态不是pending时,不能被修改状态。(参见:1)
      if (this.PromiseState !== "pending") return;
      // 修改Promise的状态和值
      this.PromiseState = "fullfilled";
      this.PromiseValue = data;
      this._toNextResolve.forEach(item => item(data));
      this._toNextResolve = [];
    }, 0);
  }

  // reject处理,同上
  triggerReject(data) {
    setTimeout(() => {
      if (this.PromiseState !== "pending") return;
      this.PromiseState = "rejected";
      this.PromiseValue = data;
      this._toNextReject.forEach(item => item(data));
      this._toNextReject = [];
    }, 0);
  }

  // 将多个Promise包装成一个新的Promise实例,并在所有异步操作执行完后执行回调
  static all(list) {
    const result = [];
    let count = 0;
    return new MyPromise(function(resolve, reject) {
      for (let [i, MyPromiseInstance] of list.entries()) {
        MyPromiseInstance.then(
          res => {
            result[i] = res;
            count++;
            if (count === list.length) resolve(result);
          },
          err => {
            reject(err);
          }
        );
      }
    });
  }

  static race(list) {
    return new MyPromise(function(resolve, reject) {
      for (let [i, MyPromiseInstance] of list.entries()) {
        MyPromiseInstance.then(
          res => {
            resolve(res);
          },
          err => {
            reject(err);
          }
        );
      }
    });
  }

  // static resolve(val) {
  //   return new MyPromise(resolve=>resolve(val));
  // }

  // static reject(val) {
  //   return new MyPromise(resolve=>{}, reject=>reject(val));
  // }
}

MyPromise.prototype.then = function(onResolved, onRejected) {
  const { PromiseState, PromiseValue } = this;

  // then方法必须返回一个Promise对象。(参见:2.7)
  return new MyPromise((onNextResolved, onNextRejected) => {
    function onLastFullFilled(val) {
      if (typeof onResolved !== "function") {
        // 如果onResolved不是函数,则需要忽略他。(参见:2.1)
        onNextResolved(val);
      } else {
        const res = onResolved(val);
        if (res && typeof res.then === "function") {
          // 若res 是一个 promise
          res.then(onNextResolved);
        } else {
          // 若res 非 promise,则直接执行下一个 onNextResolved
          onNextResolved(res);
        }
      }
    }
    function onLastRejected(val) {
      if (typeof onRejected !== "function") {
        // 如果onRejected不是函数,则需要忽略他。(参见:2.1)
        onNextRejected(val);
      } else {
        const res = onRejected(val);
        if (res && typeof res.then === "function") {
          // 若res 是一个 promise
          res.then(onNextRejected);
        } else {
          // 若res 非 promise,则直接执行下一个 onNextRejected
          onNextRejected(res);
        }
      }
    }
    switch (PromiseState) {
      case "pending": {
        this._toNextResolve.push(onLastFullFilled);
        this._toNextReject.push(onLastRejected);
        break;
      }
    }
  });
};

const p1 = function() {
  return new MyPromise(function(resolve, reject) {
    setTimeout(function() {
      const random = Math.random() * 10;
      if (random > 5) {
        resolve("已完成1:" + random);
      } else {
        reject("已拒绝1:" + random);
      }
    }, 1000);
  });
};

const p2 = function() {
  return new MyPromise(function(resolve, reject) {
    const random = Math.random() * 10;
    resolve("已完成2:" + random);
  });
};

const p3 = function() {
  return new MyPromise(function(resolve, reject) {
    const random = Math.random() * 10;
    resolve("已完成3:" + random);
  });
};

p1().then(
  res => {
    console.log('then方法:');
    console.log(res);
  },
  err => {
    console.log('then方法:');
    console.log(err);
  }
);

MyPromise.all([p1(), p2(), p3()]).then(
  res => {
    console.log('all方法:');
    console.log(res);
  },
  err => {
    console.log('all方法:');
    console.log(err);
  }
);

MyPromise.race([p1(), p2(), p3()]).then(
  res => {
    console.log('race方法:');
    console.log(res);
  },
  err => {
    console.log('race方法:');
    console.log(err);
  }
);

标签:function,resolve,res,详解,Promise,promise,手写,onRejected
来源: https://blog.csdn.net/weixin_40005545/article/details/111241833