实现一个符合 Promise/A+ 规范的 MyPromise
Promise
实现一个符合 Promise/A+ 规范的 MyPromise,并实现 resolve、reject、all、race、defer、deferred等静态方法。
MyPromise
- 作用:创建
MyPromise
实例。Promise - MyPromise接收一个回掉函数
executor
- MyPromise状态
- pending
- 可以转换成 fulfilled 或 rejected
- fulfilled
- 不可改变成其他状态
- rejected
- 不可改变成其他状态
- pending
onFulfilledCallbacks
和onRejectedCallbacks
- 两个数组,数组每一项是一个函数。分别接收
then
里面的第一个参数和第二个参数。 - 状态是
pending
的回掉函数。
- 两个数组,数组每一项是一个函数。分别接收
- resolve
promise
的状态是fulfilled
异常是的处理函数- 接收
value
参数- 如果是
promise
,执行then
。 - 如果不是
promise
,把value
做为参数传给onFulfilledCallbacks
里的每个函数。
- 如果是
- reject
promise
的状态是rejected
异常是的处理函数- 接收
reason
参数,把reason
做为参数传给onRejectedCallbacks
里的每个函数。
- 执行
executor
,如果有异常,抛给reject
- 因为
Promise
是在同步代码执行完成后再执行,所以要把Mypromise
的执行方法resolve
和reject
放在异步队列里
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
- 作用:接收两个函数参数,第一个函数的参数是
resolve
传入的参数,第二个参数是reject
传入的参数。Promise#then onFulfilled
MyPromise
成功时执行的方法resolve
的参数会作为value
传给onFulfilled
onRejected
MyPromise
失败时执行的方法reject
的参数会作为value
传给onRejected
- 返回一个
MyPromise
实例newPromise
,方便链式调用 - 对三种状态分别处理
- 每个状态中创建
newPromise
fulfilled
- 直接执行
onFulfilled
,返回值x
- 把
newPromise
、x
以及newPromise
里的resolve
、reject
做为参数传给resolutionPromise
- 把 MyPromise 的参数放在异步队列里
- 直接执行
rejected
- 直接执行
onRejected
,返回值x
- 把
newPromise
、x
以及newPromise
里的resolve
、reject
做为参数传给resolutionPromise
- 把 MyPromise 的参数放在异步队列里
- 直接执行
pending
- 状态待定,把
fulfilled
和rejected
里的异步函数分别加到onFulfilledCallbacks
和onRejectedCallbacks
的最后一位
- 状态待定,把
- 每个状态中创建
resolutionPromise
后面细说- 用
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
- 作用:捕获异常
- 返回
MyPromise
MyPromise.prototype.catch = function (onRejected) {return this.then(undefined, onRejected);
};
复制代码
The Promise Resolution Procedure
- Promise解析过程,是以一个
promise
、一个值x
及resolve
,reject
做为参数的抽象过程 promise
等于x
,reject
抛出异常new TypeError('循环引用')
x
如果不是对象(不包括null
)或者函数,执行resolve(x)
- 获取
x.then
赋值给then
then
如果是function
- 把
x
做为this
调用then
,第一个参数是resolvePromise
,第二个参数是rejectPromise
resolvePromise
和rejectPromise
只有第一次调用有效resolvePromise
参数为y
,执行resolutionPromise(promise, y, resolve, reject)
rejectPromise
参数为r
,执行reject(r)
- 把
then
如果不是function
- 执行
resolve(x)
- 执行
- 用捕获上一步的异常
- 执行
reject(e)
- 如果执行过
resolvePromise
或rejectPromise
,忽略
- 执行
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相关推荐
- 深入理解Promise并写一个符合Promise a+规范的Promise代码
深入理解Promise并写一个符合Promise a+规范的Promise代码 关于Promise函数可以参考我写的这篇文章https://www.cnblogs.com/qiaohong/p/770 ...
- 方法 手写promise_实现一个符合 Promise/A+规范的 Promise(typescript 版)
(给前端大全加星标,提升前端技能) 转自:Col0ring juejin.cn/post/6886360224308035598 写在前面 没错,这又是一篇关于手写 Promise 的文章,想必大家已 ...
- 一步步写一个符合Promise/A+规范的库
Promise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果. ES6 中采用了 Promise/A+ 规范,Promise 实现之前,当然要先了解 Promise/A+ 规范,规范地 ...
- 一步步写一个符合Promise/A+规范的库 1
Promise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果. ES6 中采用了 Promise/A+ 规范,Promise 实现之前,当然要先了解 Promise/A+ 规范,规范地 ...
- 实现一个完美符合Promise/A+规范的Promise
原文在我的博客中:原文地址 如果文章对您有帮助,您的star是对我最好的鼓励- 简要介绍:Promise允许我们通过链式调用的方式来解决"回调地狱"的问题,特别是在异步过程中,通过 ...
- 手写一款符合Promise/A+规范的Promise
手写一款符合Promise/A+规范的Promise 长篇预警!有点长,可以选择性观看.如果对Promise源码不是很清楚,还是推荐从头看,相信你认真从头看到尾,并且去实际操作了,肯定会有收获的.主要 ...
- 手把手带你实现符合Promise/A+规范的Promise
文章目录 手把手带你实现符合Promise/A+规范的Promise 什么是Promise/A+规范? 一步步实现自定义Promise 构造函数 resolve 与 reject的构建与基础实现 th ...
- 写一个符合 Promises/A+ 规范并可配合 ES7 async/await 使用的 Promise
原文地址 从历史的进程来看,Javascript 异步操作的基本单位已经从 callback 转换到 Promise.除了在特殊场景使用 stream,RxJs 等更加抽象和高级的异步数据获取和操作流 ...
- Promise的源码实现(完美符合Promise/A+规范)
Promise是前端面试中的高频问题,我作为面试官的时候,问Promise的概率超过90%,据我所知,大多数公司,都会问一些关于Promise的问题.如果你能根据PromiseA+的规范,写出符合规范 ...
最新文章
- AI项目成功的4要素
- 算法-----第一个错误的版本
- qt交叉编译环境搭建方法
- GLEW_ERROR_NO_GL_VERSION的解决方法
- 转载:如何开发高性能低成本的网站之技术选择
- 小米手机解锁,root
- Origin修改安装位数
- 1156针最强cpu,1156的CPU什么最好?
- 跨越阶层,至少需要三代人的努力;看千年前的眉山五苏是如何完成的
- 如果有一天我老无所依,请把我埋在,新疆的田野上
- [翻译]在Windows版或MacOS版的Microsoft Edge上安装一个谷歌浏览器拓展
- java 163 授权码_JavaMail使用163,sina邮箱,发送失败
- 网格化管理服务系统,携同用户创新共进步
- 写推文满一年,分享 5 个小编常用的写作软件
- Android 性能优化必知必会
- Pycharm更换清华、阿里、豆瓣软件源提高依赖包下载速度
- 今日趣闻|植物人老板
- jsp+ssm计算机毕业设计 宠物医院管理系统【附源码】
- Harmonic function
- Mac OS平台上全世界上最广泛使用的扫描仪驱程序,能够随时随地为旧的扫描仪创建驱动程序