首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >从零实现 promise 的 class 和 function 版本

从零实现 promise 的 class 和 function 版本

作者头像
白墨石
发布于 2023-09-28 01:22:27
发布于 2023-09-28 01:22:27
19400
代码可运行
举报
文章被收录于专栏:生信情报站生信情报站
运行总次数:0
代码可运行

Class 版

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class mPromise {
  // 构造器
  constructor(executor) {
    // 添加属性
    this.PromiseState = "pending";
    this.PromiseResult = null;
    this.callbacks = [];
    const _this = this;

    function resolve(data) {
      if (_this.PromiseState !== "pending") return;
      _this.PromiseState = "fulfilled";
      _this.PromiseResult = data;

      // 执行 then onResolved 回调函数
      setTimeout(() => {
        _this.callbacks.forEach((item) => {
          item.onResolved(data);
        });
      });
    }

    function reject(data) {
      if (_this.PromiseState !== "pending") return;
      _this.PromiseState = "rejected";
      _this.PromiseResult = data;

      // 执行 then onRejected 回调函数
      setTimeout(() => {
        _this.callbacks.forEach((item) => {
          item.onRejected(data);
        });
      });
    }

    try {
      executor(resolve, reject);
    } catch (e) {
      reject(e);
    }
  }

  // then 方法
  then(onResolved, onRejected) {
    const _this = this;

    // 判断回调函数数组中是否是正确的回调函数
    // 用于实现 catch 的异常穿透,添加默认的 onRejected 回调函数
    if (typeof onRejected !== "function") {
      // 如果不是函数,就创建一个函数,抛出异常
      onRejected = (err) => {
        throw err;
      };
    }

    // then 没有指定 onResolved 回调函数,添加默认的 onResolved 回调函数
    if (typeof onResolved !== "function") {
      onResolved = (val) => val;
    }

    return new mPromise((resolve, reject) => {
      // 封装回调函数
      function callback(onResult) {
        try {
          const result = onResult(_this.PromiseResult);
          if (result instanceof mPromise) {
            result.then(
              (val) => {
                resolve(val);
              },
              (err) => {
                reject(err);
              }
            );
          } else {
            resolve(result);
          }
        } catch (e) {
          reject(e);
        }
      }

      // 调用回调函数
      if (this.PromiseState === "fulfilled") {
        setTimeout(() => {
          callback(onResolved);
        });
      }

      if (this.PromiseState === "rejected") {
        setTimeout(() => {
          callback(onRejected);
        });
      }

      if (this.PromiseState === "pending") {
        // 保存回调函数
        // 使用数组保存是为了解决多次调用then方法的问题
        this.callbacks.push({
          onResolved: () => {
            callback(onResolved);
          },
          onRejected: () => {
            callback(onRejected);
          },
        });
      }
    });
  }

  // catch 方法
  catch(onRejected) {
    return this.then(undefined, onRejected);
  }

  // resolve 方法, 是对象方法,不属于实例对象方法
  static resolve(value) {
    return new mPromise((resolve, reject) => {
      if (value instanceof mPromise) {
        value.then(
          (val) => {
            resolve(val);
          },
          (err) => {
            reject(err);
          }
        );
      } else {
        resolve(value);
      }
    });
  }

  // reject 方法, 是对象方法,不属于实例对象方法
  static reject(err) {
    return new mPromise((resolve, reject) => {
      reject(err);
    });
  }

  // all 方法
  static all(promises) {
    return new mPromise((resolve, reject) => {
      let count = 0;
      const arr = [];
      promises.forEach((promise, i) => {
        promise.then(
          (val) => {
            arr[i] = val;
            count++;
            if (count === promises.length) {
              resolve(arr);
            }
          },
          (err) => {
            reject(err);
          }
        );
      });
    });
  }

  // race 方法
  static race(promises) {
    return new mPromise((resolve, reject) => {
      promises.forEach((promise) => {
        promise.then(
          (val) => {
            resolve(val);
          },
          (err) => {
            reject(err);
          }
        );
      });
    });
  }
}

function 版

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 声明构造函数
function mPromise(executor) {
  // 添加属性
  this.PromiseState = "pending";
  this.PromiseResult = null;
  this.callbacks = [];
  const _this = this;

  function resolve(data) {
    if (_this.PromiseState !== "pending") return;
    _this.PromiseState = "fulfilled";
    _this.PromiseResult = data;

    // 执行 then onResolved 回调函数
    setTimeout(() => {
      _this.callbacks.forEach((item) => {
        item.onResolved(data);
      });
    });
  }

  function reject(data) {
    if (_this.PromiseState !== "pending") return;
    _this.PromiseState = "rejected";
    _this.PromiseResult = data;

    // 执行 then onRejected 回调函数
    setTimeout(() => {
      _this.callbacks.forEach((item) => {
        item.onRejected(data);
      });
    });
  }

  try {
    executor(resolve, reject);
  } catch (e) {
    reject(e);
  }
}

mPromise.prototype.then = function (onResolved, onRejected) {
  const _this = this;

  // 判断回调函数数组中是否是正确的回调函数
  // 用于实现 catch 的异常穿透,添加默认的 onRejected 回调函数
  if (typeof onRejected !== "function") {
    // 如果不是函数,就创建一个函数,抛出异常
    onRejected = (err) => {
      throw err;
    };
  }

  // then 没有指定 onResolved 回调函数,添加默认的 onResolved 回调函数
  if (typeof onResolved !== "function") {
    onResolved = (val) => val;
  }

  return new mPromise((resolve, reject) => {
    // 封装回调函数
    function callback(onResult) {
      try {
        const result = onResult(_this.PromiseResult);
        if (result instanceof mPromise) {
          result.then(
            (val) => {
              resolve(val);
            },
            (err) => {
              reject(err);
            }
          );
        } else {
          resolve(result);
        }
      } catch (e) {
        reject(e);
      }
    }

    // 调用回调函数
    if (this.PromiseState === "fulfilled") {
      setTimeout(() => {
        callback(onResolved);
      });
    }

    if (this.PromiseState === "rejected") {
      setTimeout(() => {
        callback(onRejected);
      });
    }

    if (this.PromiseState === "pending") {
      // 保存回调函数
      // 使用数组保存是为了解决多次调用then方法的问题
      this.callbacks.push({
        onResolved: () => {
          callback(onResolved);
        },
        onRejected: () => {
          callback(onRejected);
        },
      });
    }
  });
};

mPromise.prototype.catch = function (onRejected) {
  return this.then(undefined, onRejected);
};

// 注意:这里是函数对象方法,不是实例对象方法
mPromise.resolve = function (value) {
  return new mPromise((resolve, reject) => {
    if (value instanceof mPromise) {
      value.then(
        (val) => {
          resolve(val);
        },
        (err) => {
          reject(err);
        }
      );
    } else {
      resolve(value);
    }
  });
};

mPromise.reject = function (err) {
  return new mPromise((resolve, reject) => {
    reject(err);
  });
};

mPromise.all = function (promises) {
  return new mPromise((resolve, reject) => {
    let count = 0;
    const arr = [];
    promises.forEach((promise, i) => {
      promise.then(
        (val) => {
          arr[i] = val;
          count++;
          if (count === promises.length) {
            resolve(arr);
          }
        },
        (err) => {
          reject(err);
        }
      );
    });
  });
};

mPromise.race = function (promises) {
  return new mPromise((resolve, reject) => {
    promises.forEach((promise) => {
      promise.then(
        (val) => {
          resolve(val);
        },
        (err) => {
          reject(err);
        }
      );
    });
  });
};
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
手写一个Promise
Nginx-传智播客链接:https://pan.baidu.com/s/1gF3gJgqnSg03rsYrSYJNtg
用户10106350
2022/10/28
2380
js-手撕8
promise的状态一开始是pending,只能从pending变为resolved或从pending变为rejected。并且是不可逆的。
赤蓝紫
2023/01/01
5940
带你手写Promise身上的几个方法,拷打面试官
Promise的手写是面试中一个常考的考点。希望我的文章能够帮到大家,在被问到Promise时能够露出一个自信的微笑。
用户6256742
2024/06/30
1450
JS高阶(一)Promise
作用:存储对象失败或成功的结果; 修改:resolve、reject 函数可以修改 result 的值;
DioxideCN
2022/08/05
2.6K0
看了就会,手写Promise原理,最通俗易懂的版本!!!
大家好,我是林三心,相信大家在日常开发中都用过Promise,我一直有个梦想,就是以最通俗的话,讲最复杂的知识,所以我把通俗易懂放在了首位,今天就带大家手写实现以下Promise吧,相信大家一看就懂。
用户6256742
2024/05/17
8400
看了就会,手写Promise原理,最通俗易懂的版本!!!
手写一个符合Promise A+规范的Promise实现
记得之前发过一篇关于Promise文章的讲解,不过都不是很深入,只是对使用上的理解,所以这次我将会带着各位通过JavaScript来实现一个Promise,并且是符合规范的,最后可以通过promises-aplus-tests来进行跑测。
吴佳
2022/09/26
7080
手写Promise,理解内部原理
1class myPromise { 2 // 为了统一用static创建静态属性,用来管理状态 3 static PENDING = "pending"; 4 static FULFILLED = "fulfilled"; 5 static REJECTED = "rejected"; 6 7 // 构造函数:通过new命令生成对象实例时,自动调用类的构造函数 8 constructor(func) { 9
心念
2023/01/11
2870
web前端面试题:您能读懂的Promise源码实现(手写代码)
2、Promise 对象存在三种状态:Pending(进行中)、resolved(已成功)、rejected(已失败)。我们可以将其设置为三个常量:
用户1272076
2020/08/21
9330
web前端面试题:您能读懂的Promise源码实现(手写代码)
promise知识盲区整理
promise执行器函数中的reslove和reject函数的执行,会改变promise对象的状态,一个是成功,一个是失败,如果没执行者两个函数,那还是未决定状态
大忽悠爱学习
2021/11/15
6920
前端二面手写面试题总结
then 方法返回一个新的 promise 实例,为了在 promise 状态发生变化时(resolve / reject 被调用时)再执行 then 里的函数,我们使用一个 callbacks 数组先把传给then的函数暂存起来,等状态改变时再调用。
helloworld1024
2022/10/27
8750
Promise 原理探究
你真的了解Promise吗?对我而言,除了知道如何使用then解决回调地狱以外,其他的还真的一知半解。虽然ES6的generator和ES7的async await提供了更先进的异步编程解决方案,但是它们还是离不开Promise,比如generator的co库的实现以及await后面必须返回promise。因此有必要深入了解一下Promise的原理。
elson
2018/06/17
2.3K0
Promise 原理探究
模拟实现 Promise(小白版)
本篇来讲讲如何模拟实现一个 Promise 的基本功能,网上这类文章已经很多,本篇笔墨会比较多,因为想用自己的理解,用白话文来讲讲
请叫我大苏
2019/12/20
1.5K0
ES6-Promise 65行代码手撕Promise
那么首先,如果你不知道Promise,你可能需要绕道先去学习一下,因为这里不想啰嗦要直接动手写滴哦
源心锁
2022/08/12
2610
ES6-Promise 65行代码手撕Promise
图解 Promise 实现原理(四)—— Promise 静态方法实现
了用法,原生提供了Promise对象。更多关于 Promise 的介绍请参考阮一峰老师的 ES6入门 之 Promise 对象。
2020labs小助手
2020/06/01
9200
写给前端小白的「Promise备忘手册」!(建议收藏)
大家好,我是HoMeTown,Promise想必大家都知道,在平时的开发工程中也经常会有用到,但是Promise作为ES6的重要特性,其实还拥有很多丰富的知识,本文面向比较初级一些的同学,可以帮你搞懂Promise到底做了什么,顺便起到一个备忘录的作用。
HoMeTown
2022/10/26
4720
写给前端小白的「Promise备忘手册」!(建议收藏)
图解 Promise 实现原理(三)—— Promise 原型方法实现
Promise 是异步编程的一种解决方案,它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。更多关于 Promise 的介绍请参考阮一峰老师的 ES6入门 之 Promise 对象。
2020labs小助手
2020/05/18
9710
前端异步技术之Promise
由于是参(抄)考(袭)前辈的polyfill,自己编码测试时出现了两处错误,ES6 Promise 规范的2.3.1和2.3.4
Jack Chen
2019/03/06
5470
从零开始写一个符合Promises/A+规范的promise
Promise 是异步编程的一种解决方案,比传统的解决方案回调函数和事件更合理更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。本篇不注重讲解promise的用法,关于用法,可以看阮一峰老师的ECMAScript 6系列里面的Promise部分:
Nealyang
2019/09/29
1.6K0
从零开始写一个符合Promises/A+规范的promise
手写一个Promise Class版本及Promise的api使用方法
Promise构造函数: Promise (excutor) {} excutor函数: 同步执行 (resolve, reject) => {} resolve函数: 内部定义成功时我们调用的函数 value => {} reject函数: 内部定义失败时我们调用的函数 reason => {} 说明:
用户10106350
2022/10/28
5090
从零开始实现一个Promise
众所周知,Promise是ES6引入的新特性,旨在解决回调地狱。下面是一个简单的例子:控制接口调用顺序:
helloworld1024
2022/10/14
2000
相关推荐
手写一个Promise
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档