Promise

实现一个符合 Promise/A+ 规范的 MyPromise,并实现 resolve、reject、all、race、defer、deferred等静态方法。

MyPromise

  1. 作用:创建 MyPromise实例。Promise
  2. MyPromise接收一个回掉函数 executor
  3. MyPromise状态
    • pending

      • 可以转换成 fulfilled 或 rejected
    • fulfilled
      • 不可改变成其他状态
    • rejected
      • 不可改变成其他状态
  4. onFulfilledCallbacksonRejectedCallbacks
    • 两个数组,数组每一项是一个函数。分别接收then里面的第一个参数和第二个参数。
    • 状态是 pending 的回掉函数。
  5. resolve
    • promise的状态是fulfilled异常是的处理函数
    • 接收 value 参数
      • 如果是promise,执行then
      • 如果不是promise,把value做为参数传给onFulfilledCallbacks里的每个函数。
  6. reject
    • promise的状态是rejected异常是的处理函数
    • 接收 reason 参数,把reason做为参数传给onRejectedCallbacks里的每个函数。
  7. 执行 executor,如果有异常,抛给reject
  8. 因为Promise是在同步代码执行完成后再执行,所以要把Mypromise的执行方法resolvereject放在异步队列里
function MyPromise(executor) {if (typeof executor !== 'function') {throw new TypeError('Promise resolver ' + executor + ' is not a function');}let self = this;this.status = 'pending';this.value = undefined;this.reason = undefined;this.onFulfilledCallbacks = [];this.onRejectedCallbacks = [];function resolve(value) {if (value instanceof MyPromise) {return value.then(resolve, reject);}if (self.status === 'pending') {self.value = value;self.status = 'fulfilled';self.onFulfilledCallbacks.forEach(item => item(value));}}function reject(reason) {if (self.status === 'pending') {self.reason = reason;self.status = 'rejected';  self.onRejectedCallbacks.forEach(item => item(reason));}}try {executor(resolve, reject);} catch (e) {reject(e);}
}复制代码

MyPromise.prototype.then

  1. 作用:接收两个函数参数,第一个函数的参数是 resolve传入的参数,第二个参数是 reject传入的参数。Promise#then
  2. onFulfilled
    • MyPromise 成功时执行的方法
    • resolve 的参数会作为value传给 onFulfilled
  3. onRejected
    • MyPromise 失败时执行的方法
    • reject 的参数会作为value传给 onRejected
  4. 返回一个 MyPromise 实例 newPromise,方便链式调用
  5. 对三种状态分别处理
    • 每个状态中创建 newPromise
    • fulfilled
      • 直接执行 onFulfilled,返回值x
      • newPromisex以及newPromise里的resolvereject做为参数传给 resolutionPromise
      • 把 MyPromise 的参数放在异步队列里
    • rejected
      • 直接执行 onRejected,返回值x
      • newPromisex以及newPromise里的resolvereject做为参数传给 resolutionPromise
      • 把 MyPromise 的参数放在异步队列里
    • pending
      • 状态待定,把fulfilledrejected里的异步函数分别加到 onFulfilledCallbacksonRejectedCallbacks的最后一位
  6. resolutionPromise 后面细说
  7. catch捕获异常,执行 reject
MyPromise.prototype.then = function (onFulfilled, onRejected) {let self = this;typeof onFulfilled !== 'function' && (onFulfilled = function (value) {return value;});typeof onRejected !== 'function' && (onRejected = function (reason) {throw reason;});let newPromise;/***  分别处理实例的三种状态*/if (self.status === 'fulfilled') {newPromise = new MyPromise(function (resolve, reject) {setTimeout(function () {try {let x = onFulfilled(self.value);resolutionPromise(newPromise, x, resolve, reject);} catch (e) {reject(e);}});});}if (self.status === 'rejected') {newPromise = new MyPromise(function (resolve, reject) {setTimeout(function () {try {let x = onRejected(self.reason);resolutionPromise(newPromise, x, resolve, reject);} catch (e) {reject(e);}});});}if (self.status === 'pending') {newPromise = new MyPromise(function (resolve, reject) {self.onFulfilledCallbacks.push(function (value) {setTimeout(function () {try {let x = onFulfilled(value);resolutionPromise(newPromise, x, resolve, reject);} catch (e) {reject(e);}});});self.onRejectedCallbacks.push(function (reason) {setTimeout(function () {try {let x = onRejected(reason);resolutionPromise(newPromise, x, resolve, reject);} catch (e) {reject(e);}});});});}return newPromise;
};复制代码

MyPromise.prototype.catch

  1. 作用:捕获异常
  2. 返回 MyPromise
MyPromise.prototype.catch = function (onRejected) {return this.then(undefined, onRejected);
};
复制代码

The Promise Resolution Procedure

  1. Promise解析过程,是以一个 promise、一个值 xresolve, reject做为参数的抽象过程
  2. promise 等于 xreject 抛出异常 new TypeError('循环引用')
  3. x如果不是对象(不包括 null)或者函数,执行 resolve(x)
  4. 获取 x.then 赋值给 then
    • then 如果是 function

      • x做为 this 调用then,第一个参数是 resolvePromise,第二个参数是 rejectPromise
      • resolvePromiserejectPromise只有第一次调用有效
      • resolvePromise参数为 y,执行 resolutionPromise(promise, y, resolve, reject)
      • rejectPromise参数为 r,执行 reject(r)
    • then 如果不是 function
      • 执行 resolve(x)
  5. 用捕获上一步的异常
    • 执行 reject(e)
    • 如果执行过 resolvePromiserejectPromise,忽略
function resolutionPromise(promise, x, resolve, reject) {if (promise === x) {reject(new TypeError('循环引用'));}let then, called;if (x !== null && (typeof x === 'object' || typeof x === 'function')) {try {then = x.then;if (typeof then === 'function') {then.call(x, function (y) {if (called)return;called = true;resolutionPromise(promise, y, resolve, reject);}, function (r) {if (called)return;called = true;reject(r);})} else {resolve(x);}} catch (e) {if (called)return;reject(e);}} else {resolve(x);}
}
复制代码

MyPromise 静态方法

MyPromise.all

  • 作用:Promise.all
MyPromise.all = function (promises) {let called = false;return new MyPromise(function (resolve, reject) {let newArr = [], count = 0;for (let i = 0; i < promises.length; i++) {let item = promises[i];if (!(item instanceof MyPromise)) {item = MyPromise.resolve(item);}item.then(function (data) {if (!called) {newArr[i] = data;if (i == count) {resolve(newArr);count++;}}}, function (e) {if (!called) {reject(e);called = true;}});}});
};
复制代码

MyPromise.race

  • 作用:Promise.race
MyPromise.race = function (promises) {return new MyPromise(function (resolve, reject) {let called = false;for (let i = 0; i < promises.length; i++) {let item = promises[i];if (!(item instanceof MyPromise)) {item = MyPromise.resolve(item);}item.then(function (data) {if (!called) {resolve(data);called = true;}}, function (e) {if (!called) {reject(e);called = true;}});}})
};
复制代码

MyPromise.resolve

  • 作用:Promise.resolve
MyPromise.resolve = function (value) {if (value instanceof MyPromise) {return value;}return new MyPromise(function (resolve, reject) {if (typeof value !== null && typeof value === 'object' && typeof value.then === 'function') {value.then();} else {resolve(value);}})
};
复制代码

MyPromise.reject

  • 作用:Promise.reject
MyPromise.reject = function (e) {return new MyPromise(function (resolve, reject) {reject(e);})
};
复制代码

test

  • npm i -g promises-aplus-tests
  • promises-aplus-tests Promise.js

源码

  • Promise.js
参考资料
  • Promise/A+规范
  • Promise/A+规范(英文)
  • JavaScript Promise迷你书(中文版)

实现一个符合 Promise/A+ 规范的 MyPromise相关推荐

  1. 深入理解Promise并写一个符合Promise a+规范的Promise代码

    深入理解Promise并写一个符合Promise a+规范的Promise代码 关于Promise函数可以参考我写的这篇文章https://www.cnblogs.com/qiaohong/p/770 ...

  2. 方法 手写promise_实现一个符合 Promise/A+规范的 Promise(typescript 版)

    (给前端大全加星标,提升前端技能) 转自:Col0ring juejin.cn/post/6886360224308035598 写在前面 没错,这又是一篇关于手写 Promise 的文章,想必大家已 ...

  3. 一步步写一个符合Promise/A+规范的库

    Promise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果. ES6 中采用了 Promise/A+ 规范,Promise 实现之前,当然要先了解 Promise/A+ 规范,规范地 ...

  4. 一步步写一个符合Promise/A+规范的库 1

    Promise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果. ES6 中采用了 Promise/A+ 规范,Promise 实现之前,当然要先了解 Promise/A+ 规范,规范地 ...

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

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

  6. 手写一款符合Promise/A+规范的Promise

    手写一款符合Promise/A+规范的Promise 长篇预警!有点长,可以选择性观看.如果对Promise源码不是很清楚,还是推荐从头看,相信你认真从头看到尾,并且去实际操作了,肯定会有收获的.主要 ...

  7. 手把手带你实现符合Promise/A+规范的Promise

    文章目录 手把手带你实现符合Promise/A+规范的Promise 什么是Promise/A+规范? 一步步实现自定义Promise 构造函数 resolve 与 reject的构建与基础实现 th ...

  8. 写一个符合 Promises/A+ 规范并可配合 ES7 async/await 使用的 Promise

    原文地址 从历史的进程来看,Javascript 异步操作的基本单位已经从 callback 转换到 Promise.除了在特殊场景使用 stream,RxJs 等更加抽象和高级的异步数据获取和操作流 ...

  9. Promise的源码实现(完美符合Promise/A+规范)

    Promise是前端面试中的高频问题,我作为面试官的时候,问Promise的概率超过90%,据我所知,大多数公司,都会问一些关于Promise的问题.如果你能根据PromiseA+的规范,写出符合规范 ...

最新文章

  1. AI项目成功的4要素
  2. 算法-----第一个错误的版本
  3. qt交叉编译环境搭建方法
  4. GLEW_ERROR_NO_GL_VERSION的解决方法
  5. 转载:如何开发高性能低成本的网站之技术选择
  6. 小米手机解锁,root
  7. Origin修改安装位数
  8. 1156针最强cpu,1156的CPU什么最好?
  9. 跨越阶层,至少需要三代人的努力;看千年前的眉山五苏是如何完成的
  10. 如果有一天我老无所依,请把我埋在,新疆的田野上
  11. [翻译]在Windows版或MacOS版的Microsoft Edge上安装一个谷歌浏览器拓展
  12. java 163 授权码_JavaMail使用163,sina邮箱,发送失败
  13. 网格化管理服务系统,携同用户创新共进步
  14. 写推文满一年,分享 5 个小编常用的写作软件
  15. Android 性能优化必知必会
  16. Pycharm更换清华、阿里、豆瓣软件源提高依赖包下载速度
  17. 今日趣闻|植物人老板
  18. jsp+ssm计算机毕业设计 宠物医院管理系统【附源码】
  19. Harmonic function
  20. Mac OS平台上全世界上最广泛使用的扫描仪驱程序,能够随时随地为旧的扫描仪创建驱动程序

热门文章

  1. js数组往队头添加数据、js数组从队头移出数据
  2. 使用Comparable、Comparator接口实现对对象数组、List集合自定义排序
  3. 电子书下载:Ultra-Fast ASP.NET 4.5 2nd
  4. java byte 梳理
  5. 条款12:复制对象时勿忘其每一个部分
  6. HttpNotificationChannel 云端推送信息实现
  7. 阿里二面:group by 怎么优化?
  8. 一个员工的离职成本有多恐怖!
  9. 致歉!抖音Semi Design承认参考阿里Ant Design
  10. 再招一万人!疯了。。。