自己写一个Promise
参考Promise 的 官方规范 https://promisesaplus.com/
Promise 其实就是一个状态机
它只有两种状态变化 pending =》 fulfilled
pending =》 rejected
并且状态一旦发生变化后就不会再改变
我们用es5来实现下
先写个架子, 并测试下:
function myPromise(executor) {
var _this = this; // 保存当前的函数上下文
_this.status = 'pending'; // 初始状态
_this.resolveValue = null; // resolve初始值
_this.rejectValue = null; // reject初始值
function resolve(value) {
if (_this.status == 'pending') {
_this.status = 'Fulfilled';
_this.resolveValue = value;
}
}
function reject(reason) {
if (_this.status == 'pending') {
_this.status = 'Fulfilled';
_this.rejectValue = reason;
}
}
try { // 捕获错误
executor(resolve, reject)
} catch (e){
reject(e);
}
}
myPromise.prototype.then = function (onFulfilled, onRejected) {
var _this = this;
if (_this.status == 'Fulfilled') {
onFulfilled(_this.resolveValue)
}
if (_this.status == 'Rejected') {
onRejected(_this.rejectValue)
}
};
var p = new myPromise((resolve, reject) => {
resolve('I am handsome');
throw Error('捕获错误')
});
p.then((data) => {
console.log(data)
}, (err) => {
console.log(err)
} );
结果:

它先执行resolve 状态 变为 Fulfilled ,
然后报错 ,执行reject , 由于此时状态不是pending, 状态还是Fulfilled
Promise的核心是处理异步,
现在我们的代码并不能等待状态的改变,
接下来我们加上处理异步操作的功能, 并测试下
function myPromise(executor) {
var _this = this; // 保存当前的函数上下文
_this.status = 'pending'; // 初始状态
_this.resolveValue = null; // resolve初始值
_this.rejectValue = null; // reject初始值
_this.resolveCallbackList = []; // 存resolve的回调
_this.rejectCallbackList = []; // 存reject的回调
function resolve(value) {
if (_this.status == 'pending') {
_this.status = 'Fulfilled';
_this.resolveValue = value;
// 状态改变执行存的回调
_this.resolveCallbackList.forEach(function(ele){
if (ele) {
ele();
}
})
}
}
function reject(reason) {
if (_this.status == 'pending') {
_this.status = 'Rejected';
_this.rejectValue = reason;
// 状态改变执行存的回调
_this.rejectCallbackList.forEach(function(ele){
if (ele) {
ele();
}
})
}
}
try { // 捕获错误
executor(resolve, reject)
} catch (e){
reject(e);
}
}
myPromise.prototype.then = function (onFulfilled, onRejected) {
var _this = this;
if (_this.status == 'Fulfilled') {
onFulfilled(_this.resolveValue)
}
if (_this.status == 'Rejected') {
onRejected(_this.rejectValue)
}
// 等待状态时把回调存起来,状态改变再触发
if (_this.status == 'pending') {
_this.resolveCallbackList.push(function () {
onFulfilled(_this.resolveValue)
});
_this.rejectCallbackList.push(function () {
onRejected(_this.rejectValue)
});
}
};
var p = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve('I am handsome');
}, 0);
// throw Error('捕获错误')
});
p.then((data) => {
console.log(data)
}, (err) => {
console.log(err)
} );
结果:

自己写一个Promise的更多相关文章
- 【原】手写一个promise
上一篇文章中,我们介绍了Promise的基本使用,在这篇文章中,我们试着自己来写一个Promise,主要是学习Promise的内部机制,学习它的编程思想. !!!备注:本文写的不好,仅供自己学习之用, ...
- 掘金转载-手写一个Promise
目录 一 什么是Promise ? 二 Promises/A+ 规范 2.1 术语 2.2 基本要求 2.2.1. Promise的状态 2.2.2. Then 方法 2.3 简易版实践 2.4 进一 ...
- 手写一个Promise/A+,完美通过官方872个测试用例
前段时间我用两篇文章深入讲解了异步的概念和Event Loop的底层原理,然后还讲了一种自己实现异步的发布订阅模式: setTimeout和setImmediate到底谁先执行,本文让你彻底理解Eve ...
- 面试----你可以手写一个promise吗
参考:https://www.jianshu.com/p/473cd754311f <!DOCTYPE html> <html> <head> <meta c ...
- 手写一个promise
Promise A+ 规范:https://promisesaplus.com/ 注:以下代码没有通过 promises-aplus-tests 的全部测试,但基本功能还是全的( 测试结果: 864 ...
- 只会用就out了,手写一个符合规范的Promise
Promise是什么 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可以获取异步操作的消息.Prom ...
- 一起学习造轮子(一):从零开始写一个符合Promises/A+规范的promise
本文是一起学习造轮子系列的第一篇,本篇我们将从零开始写一个符合Promises/A+规范的promise,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Pr ...
- 请手写代码实现一个promise
第一步:promise的声明 class Promise{ // 构造器 constructor(executor){ // 成功 let resolve = () => { }; // 失败 ...
- 操刀 requirejs,自己动手写一个
前沿 写在文章的最前面 这篇文章讲的是,我怎么去写一个 requirejs . 去 github 上fork一下,顺便star~ requirejs,众所周知,是一个非常出名的js模块化工具,可以让你 ...
随机推荐
- MySQL不同数据库之间表的简单同步
MySQL不同数据库之间表的简单同步,实用轻量级数据如下案列展示:例如我现在主库上面有users .tenants两张表需要同步到备库上面主库1.确认主库数据条数 select count(*) fr ...
- POJ3696 The Luckiest Number 欧拉定理
昨天终于把欧拉定理的证明看明白了...于是兴冲冲地写了2道题,发现自己啥都不会qwq 题意:给定一个正整数L<=2E+9,求至少多少个8连在一起组成正整数是L的倍数. 这很有意思么... 首先, ...
- python_魔法方法(二):算术运算
python2.2之后,对类和类型做了同意,将int().float().str().list().touple()这些BIF转换为工厂函数 >>> type(len) <cl ...
- Windows开机自动登录及取消自动登录的设置
开机自动登录 1.开始菜单搜索框输入 “netplwiz” 按回车 或“Win+R”组合键打开“运行”框内输入“netplwiz” 或“运行”框内输入“control userpasswords2”( ...
- C# ThreadLocal
ThreadLocal的主要作用是让各个线程维持自己的变量. .NET 4.0在线程方面加入了很多东西,其中就包括ThreadLocal<T>类型,他的出现更大的简化了TLS的操作.Thr ...
- postgis 赋予postgresql空间数据库的能力
安装: Windows:postgresql的bin目录下:运行stackbuilder,一步一步按照提示来就行了 Ubuntu: apt-get install postgresql-9.3-pos ...
- C - Watchmen
题目链接:https://vjudge.net/contest/237394#problem/C Watchmen are in a danger and Doctor Manhattan toget ...
- HDU 5734 A - Acperience
http://acm.hdu.edu.cn/showproblem.php?pid=5734 Problem Description Deep neural networks (DNN) have s ...
- CountDownLatch与CyclicBarrier的使用与区别
CountDownLatch的介绍和使用: 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 co ...
- Srping MVC中Controller的void方法
第一种 通过修改response来修改页面 /** * 方式一:通过声明HttpServletResponse类型的方法入参,来使用HttpServletResponse对象. * 注意:在Contr ...