用原生js手写实现promise-程序员宅基地

技术标签: ViewUI  前端  

用原生js手写实现promise,看了网上很多实现,最终写出自己的简易版promise,记录一下

前言:使用及调用同原生Promise方法,只实现了then(resolve),catch(reject),finally()三个方法,不涉及Promise.race(),Promise.all();

  • 构造函数:
let that; // 存储 mPromise
/**
 * 因为每次 new mPromise(then, catch的时候都需要链式调用)会调用 mPromise(constructor),
 * 所以放到外面
 */
// 状态、参数配置
let config = {
  status: null,
  resolveParam: null,
  rejectParam: null
};

/**
 * mPromise函数:原生Promise的手动实现
 * @param {new mPromise时传入的回调函数} callback
 */
function mPromise(callback) {
  that = this;
  // 往new mPromise时传入的回调函数,传回两个参数
  callback(that.resolve, that.reject);
}
复制代码
  • 原型:
mPromise.prototype = {
  constructor: mPromise,
  resolve(param) {
    config.rejectParam = null; // 重置 reject 参数
    config.resolveParam = param;
    config.status = 'PENDING';
  },
  reject(param) {
    config.resolveParam = null; // 重置 resolve 参数
    config.rejectParam = param;
    config.status = 'PENDING';
  },
  then(_fn) {
    // 有resolve才调用
    if (config.resolveParam !== null) {
      config.status = 'RESOLVED';
      // 运行 then 的回调,捕获其中的报错,调用 catch
      try {
        _fn(config.resolveParam);
      } catch (err) {
        config.rejectParam = err;
        that.catch(() => {});
      }
    }
    return new mPromise(() => {});
  },
  catch(_fn) {
    // 有reject才调用
    if (config.rejectParam !== null) {
      config.status = 'REJECTED';
      _fn(config.rejectParam);
    }
    return new mPromise(() => {});
  },
  finally(_fn) {
    // 初始化配置
    config = {
      status: null,
      resolveParam: null,
      rejectParam: null
    };
    _fn();
  }
};
复制代码
  • 使用方式同原生Promise:
let f1 = function(num) {
  return new mPromise((resolve, reject) => {
    if (num < 10) resolve(num);
    else if (num === 11) reject(num);
  });
};
复制代码
  • 然后调用:
f1(6)
  .then(res => {
    // cc; 打开的话,会被 try catch捕获,触发catch,而不会往下走
    console.log('then: ', res); // then 6
  })
  .catch(err => {
    // 这里会捕获 then 里面的报错
    console.log('catch: ', err); // ReferenceError: cc is not defined
  });

f1(11)
  .then(res => {
    console.log('then: ', res);
  })
  .catch(err => {
    console.log('catch: ', err); // catch 11
  })
  .finally(() => {
    console.log('11 finally\n'); // 11 finally
  });

f1(12)
  .then(res => {
    console.log('then: ', res);
  })
  .catch(err => {
    console.log('catch: ', err);
  })
  .finally(() => {
    console.log('12 finally\n'); // 12 finally
  });
复制代码
结果:

then里面不报错:

then里面有报错:

到此,结束!

转载于:https://juejin.im/post/5cb2f5f3f265da034d2a069d

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34273479/article/details/91442662

智能推荐

python自动化运维-Python自动化运维学习资源汇总-程序员宅基地

文章浏览阅读449次。运维工种对于自动化的强烈需求已经显漏无疑——作为一个古老的技术工种,在几台、几十台服务器时尚可人肉维护,面对云计算时代动辄上百上千的服务器,单凭人肉维护显然束手无策。想像一下诸如谷歌、阿里云的上万台服务器,如果单凭人工维护恐怕运维就会成为人员需求量最高的工种,没有之一。在Devops备受推崇的时代,即使开发也难免要接触到一些运维工作。所以今天为大家整理了一些自动化运维的学习资源,希望能够给大家提供..._《python 自动化运维》(python for devops)

STM32G030F6P6烧录程序无法启动运行-程序员宅基地

文章浏览阅读2k次。原因分析,STM32G030F6P6与STM32F系列的启动特点有一些差异,主要是默认的nBOOT_SEL被设置为1,即由内部BOOT位配置启动,使用官方提供的STM32CubeProgrammer修改不了nBOOT_SEL配置,后来通过命令行执行下列代码后,修改nBOOT_SEL为0,芯片可正常启动。初次使用STM32G030F6P6开发了一款电路板,但是发现烧录程序后无法启动运行的问题。_stm32g030f6p6烧录

黑马程序员————IO流操作的基本规律和使用方法_io流操作的熟练应用-程序员宅基地

文章浏览阅读359次。O流的操作规律之所以要弄清楚这个规律,是因为流的对象太多,开发时不知道用哪个对象合适。想要知道开发时用到哪个对象,只要通过四个明确即可。1.明确源和目的(汇) 源:InputStream Reader 目的:OutputStream Writer2.明确数据是否是纯文本数据 源:是纯文本 Reader_io流操作的熟练应用

Blender基础操作:移动游标位置、快速设置原点_blender移动游标-程序员宅基地

文章浏览阅读6k次,点赞3次,收藏2次。如何快速设置原点,如何移动游标的位置_blender移动游标

友盟qq分享回调无论成功失败全部跳转onCancel_友盟分享qq oncancel-程序员宅基地

文章浏览阅读1.2k次。友盟社会化sdk,qq分享回调无论成功失败全部跳转onCancel解决方法:application中的qqid和manifests的qqid需要填写同一个,如果用默认的就全都用默认id。_友盟分享qq oncancel

【雕爷学编程】Arduino 手册之布尔运算符&&(逻辑与)_arduino &&-程序员宅基地

文章浏览阅读474次。2)布尔运算符&& (逻辑与)的操作数必须是布尔类型的值,即真(true)或假(false)。一般来说,非零的值会被转换为真(true),零的值会被转换为假(false)。因此,在使用布尔运算符&& (逻辑与)时,最好确保操作数是布尔类型的值,或者使用比较运算符将其转换为布尔类型的值。3)布尔运算符&& (逻辑与)的结果也是布尔类型的值,即真(true)或假(false)。布尔运算符&& (逻辑与)的案例四:这个案例是使用Arduino和一个超声波传感器来测量距离,并根据距离的大小显示不同的颜色。_arduino &&

随便推点

Intellij Idea 设置方法模板_idea if模板-程序员宅基地

文章浏览阅读2w次,点赞5次,收藏6次。设置Idea的方法注释模板 详细配置: /** * @author usernameusername datedate * @time timetime * @method methodmethod * @param paramparam * @return methodretur_idea if模板

MATLAB调用OpenCV流程(MATLAB R2016a+OpenCV3.1.0+VS2010)_matlab写的程序会提到opencv吗-程序员宅基地

文章浏览阅读7.2k次,点赞2次,收藏44次。第一次使用MATLAB和C++混编,综合一些网上的教程,最终实现功能,尽管理解不是很深刻,但先记录下来,以后慢慢领悟。在MATLAB命令行窗口中输入命令“mex -setup C++”,此时显示如下图所示: 在MATLAB命令行窗口中输入命令“mbulid -setup C++”,此时显示如下图所示: 此时编译环境搞定,但是得通过配置文件xml,修改前先编写一个测试代码,文件名为OpenC..._matlab写的程序会提到opencv吗

关于网络安全那点事:MYSQL使用教程-程序员宅基地

文章浏览阅读840次,点赞23次,收藏16次。从时代发展的角度看,网络安全的知识是学不完的,而且以后要学的会更多,同学们要摆正心态,既然选择入门网络安全,就不能仅仅只是入门程度而已,能力越强机会才越多。因为入门学习阶段知识点比较杂,所以我讲得比较笼统,大家如果有不懂的地方可以找我咨询,我保证知无不言言无不尽,需要相关资料也可以找我要,我的网盘里一大堆资料都在吃灰呢。干货主要有:①1000+CTF历届题库(主流和经典的应该都有了)②CTF技术文档(最全中文版)③项目源码(四五十个有趣且经典的练手项目及源码)

行政法学-第十四章:行政赔偿与行政补偿-程序员宅基地

文章浏览阅读906次,点赞19次,收藏22次。行政法学第十四章知识点

JSON parse error: Unexpected end-of-input: ... PushbackInputStream ... JsonEOFException_json parse error: unexpected end-of-input: expecte-程序员宅基地

文章浏览阅读3.2w次,点赞38次,收藏14次。错误异常信息:JSON parse error: Unexpected end-of-input: expected close marker for Object (start marker at [Source: (PushbackInputStream); line: 1, column: 1]); nested exception is com.fasterxml.jackson.cor..._json parse error: unexpected end-of-input: expected close marker for object

计算机四级网络工程师操作题,计算机四级《网络工程师》练习题-程序员宅基地

文章浏览阅读258次。计算机四级《网络工程师》练习题计算机四级是针对计算机的熟练以及掌握程度进行评估的一种国家型等级考试。考试为无纸化考试,不含操作题。下面就来和小编一起看看计算机四级《网络工程师》练习题吧。1文件系统中,文件访问控制信息存储的合理位置是A.文件控制块B.文件分配表C.用户口令表D.系统注册表参考答案:A2下列对文件的描述中,哪一项与文件的物理结构相关?A.文件长度B.用户对文件的存取方式C.文件中记录..._计算机四级 操作题