前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手写Promise

手写Promise

作者头像
前端逗逗飞
发布2022-08-30 17:25:43
5700
发布2022-08-30 17:25:43
举报
文章被收录于专栏:前端逗逗飞前端逗逗飞

前言

如果想实现一个Promise 需要从以下几个方面考虑

  • 符合 promise A+规范
  • Promise类的设计
  • 状态设计(pending/fulfilled/reject)
  • 如何实现 resolve
  • 如何实现 reject
  • 如何实现 then

什么是Promise A+ 规范

promisesaplus

  1. “promise” is an object or function with a then method whose behavior conforms to this specification.
  2. “thenable” is an object or function that defines a then method.
  3. “value” is any legal JavaScript value (including undefined, a thenable, or a promise).
  4. “exception” is a value that is thrown using the throw statement.
  5. “reason” is a value that indicates why a promise was rejected.
  6. A promise must be in one of three states: pending, fulfilled, or rejected.

promise类的设计

我们在使用 Promise的时候,都是通过 new 关键字调用, 所以借助 ES6 class 实现 Promise的声明

代码语言:javascript
复制
class DDFPromise {
  constructor(executor) {
    executor(executor);
  }

复制代码

实现Promise 三种状态

我们在使用Promise时,注意到,Promise有三种状态 fulfill/reject/pending

  • new Promise(()=> {}) 此时的状态为pending
  • new Promise(()=> {}).then() 此时的状态为fulfill
  • new Promise(()=> {}).catch() 此时的状态为reject
代码语言:javascript
复制
const PENDING_STATUS = "pending";
const FULFILL_STATUS = "fulfill";
const REJECT_STATUS = "reject";
class DDFPromise {
    constructor(executor) {
        this.status = PENDING_STATUS;
        executor(executor);
     }
}

new DDFPromise(() => {
  console.log("代码执行");
});
复制代码

如何实现 resolve

实现resolve 需要关注两个点

  • 状态
  • 返回值
代码语言:javascript
复制
const PENDING_STATUS = "pending";
const FULFILL_STATUS = "fulfill";
const REJECT_STATUS = "reject";
class DDFPromise {
    constructor(executor) {
      this.status = PENDING_STATUS;
      this.value = null;
      const resolve = (value) => {
        if (this.status === PENDING_STATUS) {
          this.status = FULFILL_STATUS;
          console.log("resolve被执行", value);
**          **this.value = value
       }
     };
      executor(resolve);
     }
}

new DDFPromise((resolve) => resolve("resolve传入的参数"))
复制代码

如何实现 reject

实现resolve 需要关注两个点

  • 状态
  • 返回值
代码语言:javascript
复制
const PENDING_STATUS = "pending";
const FULFILL_STATUS = "fulfill";
const REJECT_STATUS = "reject";
class DDFPromise {
    constructor(executor) {
      this.status = PENDING_STATUS;
      this.value = null;
      const resolve = (value) => {
        if (this.status === PENDING_STATUS) {
          this.status = FULFILL_STATUS;
          console.log("resolve被执行", value);
          this.value = value
       }
     };
      const reject = (reason) => {
        if (this.status === PENDING_STATUS) {
          this.status = REJECT_STATUS;
          this.reason = reason;
       }
     };
      executor(resolve, reject);
     }
}

new DDFPromise((resolve, reject) => {
  resolve("resolve传入的参数");
  reject("reject传入的参数");
})
复制代码

如何实现 then

实现then 需要关注 以下几点

  • then方法的两个入参
  • then方法的两个入参 如何与constructor中定义的resolve/reject做关联
代码语言:javascript
复制

const PENDING_STATUS = "pending";
const FULFILL_STATUS = "fulfill";
const REJECT_STATUS = "reject";
class DDFPromise {
  constructor(executor) {
    this.status = PENDING_STATUS;
    this.value = null;
    this.reason = null;
    const resolve = (value) => {
      if (this.status === PENDING_STATUS) {
        this.status = FULFILL_STATUS;
        this.value = value;
        this.onfulfilled(this.value);
      }
    };
    const reject = (reason) => {
      if (this.status === PENDING_STATUS) {
        this.status = REJECT_STATUS;
        this.reason = reason;
        this.onrejected(this.reason);
      }
    };
    executor(resolve, reject);
  }
  
  then(onfulfilled, onrejected) {
    this.onfulfilled = onfulfilled;
    this.onrejected = onrejected;
  }
}

const ddfPro = new DDFPromise((resolve, reject) => {
    resolve("resolve传入的参数");
    // reject("reject传入的参数");
});

ddfPro.then(
    (res) => {
      console.log("fulfilled", res);
    },
    (err) => {
      console.log("reject", err);
    }
);
复制代码

上边代码执行时报错 this.onfulfilled is not a function,报错的原因:new Prose(()=>{}) 入参的代码会立刻执行,而执行时this.onrejected,还没有声明,其实我们可以借助 Event Loop 解决此问题

解决then方法声明 调用时报错

queueMicrotask | setTimeout

代码语言:javascript
复制
const PENDING_STATUS = "pending";
const FULFILL_STATUS = "fulfill";
const REJECT_STATUS = "reject";
class DDFPromise {
  constructor(executor) {
    this.status = PENDING_STATUS;
    this.value = null;
    this.reason = null;
    const resolve = (value) => {
      if (this.status === PENDING_STATUS) {
        this.status = FULFILL_STATUS;
        queueMicrotask(() => {
          this.value = value;
          this.onfulfilled(this.value);
        });
     }
  };
  const reject = (reason) => {
    if (this.status === PENDING_STATUS) {
       this.status = REJECT_STATUS;
       queueMicrotask(() => {
         this.reason = reason;
         this.onrejected(this.reason);
       });
      }
    };
    executor(resolve, reject);
  }
  then(onfulfilled, onrejected) {
    this.onfulfilled = onfulfilled;
    this.onrejected = onrejected;
  }
}

const ddfPro = new DDFPromise((resolve, reject) => {
// resolve("resolve传入的参数");

// reject("reject传入的参数");
});

ddfPro.then(
  (res) => {
     console.log("fulfilled", res);
  },
  (err) => {
    console.log("reject", err);
  }
);
复制代码

总结

经过如上步骤,只完成了Promise的基本操作,

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-05-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 什么是Promise A+ 规范
  • promise类的设计
  • 实现Promise 三种状态
  • 如何实现 resolve
  • 如何实现 reject
  • 如何实现 then
    • 解决then方法声明 调用时报错
    • 总结
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档