Promise是前端面试中的高频问题,我作为面试官的时候,问Promise的概率超过90%,据我所知,大多数公司,都会问一些关于Promise的问题。如果你能根据PromiseA+的规范,写出符合规范的源码,那么我想,对于面试中的Promise相关的问题,都能够给出比较完美的答案。

我的建议是,对照规范多写几次实现,也许第一遍的时候,是改了多次,才能通过测试,那么需要反复的写,我已经将Promise的源码实现写了不下七遍。

Promise的源码实现

/**
 * 1. new Promise时,需要传递一个 executor 执行器,执行器立刻执行
 * 2. executor 接受两个参数,分别是 resolve 和 reject
 * 3. promise 只能从 pending 到 rejected, 或者从 pending 到 fulfilled
 * 4. promise 的状态一旦确认,就不会再改变
 * 5. promise 都有 then 方法,then 接收两个参数,分别是 promise 成功的回调 onFulfilled,  * 和 promise 失败的回调 onRejected  * 6. 如果调用 then 时,promise已经成功,则执行 onFulfilled,并将promise的值作为参数传递进去。  * 如果promise已经失败,那么执行 onRejected, 并将 promise 失败的原因作为参数传递进去。  * 如果promise的状态是pending,需要将onFulfilled和onRejected函数存放起来,等待状态确定后,再依次将对应的函数执行(发布订阅)  * 7. then 的参数 onFulfilled 和 onRejected 可以缺省  * 8. promise 可以then多次,promise 的then 方法返回一个 promise  * 9. 如果 then 返回的是一个结果,那么就会把这个结果作为参数,传递给下一个then的成功的回调(onFulfilled)  * 10. 如果 then 中抛出了异常,那么就会把这个异常作为参数,传递给下一个then的失败的回调(onRejected)  * 11.如果 then 返回的是一个promise,那么需要等这个promise,那么会等这个promise执行完,promise如果成功,  * 就走下一个then的成功,如果失败,就走下一个then的失败  */ const PENDING = 'pending'; const FULFILLED = 'fulfilled'; const REJECTED = 'rejected'; function Promise(executor) { let self = this; self.status = PENDING; self.onFulfilled = [];//成功的回调 self.onRejected = []; //失败的回调 //PromiseA+ 2.1 function resolve(value) { if (self.status === PENDING) { self.status = FULFILLED; self.value = value; self.onFulfilled.forEach(fn => fn());//PromiseA+ 2.2.6.1 } } function reject(reason) { if (self.status === PENDING) { self.status = REJECTED; self.reason = reason; self.onRejected.forEach(fn => fn());//PromiseA+ 2.2.6.2 } } try { executor(resolve, reject); } catch (e) { reject(e); } } Promise.prototype.then = function (onFulfilled, onRejected) { //PromiseA+ 2.2.1 / PromiseA+ 2.2.5 / PromiseA+ 2.2.7.3 / PromiseA+ 2.2.7.4 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value; onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }; let self = this; //PromiseA+ 2.2.7 let promise2 = new Promise((resolve, reject) => { if (self.status === FULFILLED) { //PromiseA+ 2.2.2 //PromiseA+ 2.2.4 --- setTimeout setTimeout(() => { try { //PromiseA+ 2.2.7.1 let x = onFulfilled(self.value); resolvePromise(promise2, x, resolve, reject); } catch (e) { //PromiseA+ 2.2.7.2 reject(e); } }); } else if (self.status === REJECTED) { //PromiseA+ 2.2.3 setTimeout(() => { try { let x = onRejected(self.reason); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }); } else if (self.status === PENDING) { self.onFulfilled.push(() => { setTimeout(() => { try { let x = onFulfilled(self.value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }); }); self.onRejected.push(() => { setTimeout(() => { try { let x = onRejected(self.reason); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }); }); } }); return promise2; } function resolvePromise(promise2, x, resolve, reject) { let self = this; //PromiseA+ 2.3.1 if (promise2 === x) { reject(

转载于:https://www.cnblogs.com/zhouyangla/p/10781697.html

Promise的源码实现(完美符合Promise/A+规范)相关推荐

  1. 实现一个完美符合Promise/A+规范的Promise

    原文在我的博客中:原文地址 如果文章对您有帮助,您的star是对我最好的鼓励- 简要介绍:Promise允许我们通过链式调用的方式来解决"回调地狱"的问题,特别是在异步过程中,通过 ...

  2. 前端如何修改组件库源码来封装符合自己需求的组件?

    点击上方 前端Q,关注公众号 回复加群,加入前端Q技术交流群 前端开发的同学们或许会遇到这样的问题:产品中需要实现某项功能,常用的 elementui.antd 等组件库中确实有差不多功能的组件.但实 ...

  3. 新修复h5盲盒商城砸金蛋源码(完美运行)

    搭建教程 一.测试环境: 1.linux宝塔面板 2.Nginx 1.18.0 3.MySQL 5.6.50 4.PHP-7.2 //PHP7.2安装拓展 fileinfo 删除所有禁用函数 1.创建 ...

  4. 【亲测源码】完美运营聚合易支付源码

    最近很火的易支付第三方接口源码,亲测没有问题,程序已开发好QQ钱包,微信,支付宝等第三方接口,配置参数即可使用 演示私信 ```php <?php if(isset($_GET['pid'])) ...

  5. 2023最新ChatGpt网站源码+修复完美版/输入密钥即可

    正文: 这个源码是本人花时间修复版的,不是网上那种泛滥不能用的源码,输入自己的Key密钥即可使用,需要用国外服务器搭建. 程序: wwxyos.lanzoue.com/ieytG0pr8xdc 图片:

  6. 2023最新USDT理财系统源码+代码完美流畅/框架二开/功能强大

    正文: 完整标题: 之前淘的一套PHP的理财源码,实测了下完美流畅,代码工整无错,UI简洁大方,有兴趣的朋友自己研究. 程序: wwegxs.lanzoux.com/ibfUk0l3c99a 图片:

  7. Z-BlogPHP导航主题模版源码 绿色完美版

    介绍: Z-BlogPHP导航主题绿色完美版! 内附详细安装使用说明TXT文档! 网盘下载地址: http://kekewl.org/xmlaj45mJLC0 图片:

  8. 解忧云SMS短信发送系统服务平台源码+解密完美版

    正文: 解忧云SMS短信服务平台系统,短信发送系统,全解密完美版,经过一系列修复现在程序已经可以完全使用. 并且是全解密随时可以二开,无后门,一些bug已经完全修复. 安装教程: 数据库配置文件路径  ...

  9. Java萝卜影视4.0.5源码【完美修复完整版】

    简介: 1.修复支持https打包功能 2.修复使用中长时间切换出去再进入不会卡死3.播放器客户端修复,与PC使用一个解析客户端,基本3秒内解析.PC+WAP部分 1.PC端修复明星 2.豆瓣数据获取 ...

最新文章

  1. HDU 1848 Fibonacci again and again
  2. 获取this_带你彻底弄清JavaScript的关键字this
  3. building a software for what?
  4. 将Swagger与Spring Boot REST API集成
  5. 小目标三、存储数据的表结构
  6. ASP.NET中Request.ApplicationPath、Request.FilePath、Request.Path、.Request.MapPath、Server.MapPath的区别
  7. 复制数据库(本地到阿里云)
  8. docker-compose 使用
  9. 企业供应链管理架构图
  10. 全国计算机考试cad,全国计算机高新考试AUTO CAD.doc
  11. Network--名词解释
  12. SpringBoot + Spring Cloud +Vue 管理系统前端搭建(二、visual studio code开发前端项目
  13. Nuxt入门到打包部署 Vue-SSR项目
  14. teamviewer12 linux安装,ubuntu16.04安装teamviewer12依赖包解决
  15. 陈年咖啡豆是什么?陈年咖啡能喝吗?陈年咖啡有什么特别的?
  16. Atmel 官方网站中文版
  17. 进程同步/异步的区别
  18. Hive正则表达式案例
  19. STLINk驱动安装
  20. 如何layui下select下拉框不显示或没有效果怎么办

热门文章

  1. zcmu1540(二分)
  2. 构建Android的交叉编译器、用NDK编译移植
  3. Scalability Tradeoffs: Why “The Ethereum
  4. 基于mcat开发智能合约应用(二)调用合约
  5. 关于android设备管理器的一些分析
  6. 全国计算机二级qq闪退,电脑上QQ闪退怎么回事?各个系统版本电脑QQ闪退现象的解决方法介绍...
  7. 火箭轨道计算属于什么计算机技术,2018年计算机二级高级Office每日一练 2月27日...
  8. 如何用python绘图、柱形图、线形图等_python使用Plotly绘图工具绘制散点图、线形图...
  9. 20211108 微分跟踪器
  10. .NET Core SignalR Redis底板详解(一)