自己写一个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模块化工具,可以让你 ...
随机推荐
- day13列表推导式作业详解
1.day13题目 2,用列表推导式做下列小题 (1)过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母 (2)求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数组成的元祖列表 (3)求M ...
- 【JavaScript权威指南】——逻辑与(&&)
三种用法总结: 1.布尔值计算: [成员]={false,true} 2.“真值”,“假值”计算: [假值]={false,null,undefined,0,-0,NaN,""} ...
- matplotlib 知识点11:绘制饼图(pie 函数精讲)
饼图英文学名为Sector Graph,又名Pie Graph.常用于统计学模块. 画饼图用到的方法为:matplotlib.pyplot.pie( ) #!/usr/bin/env python # ...
- python_魔法方法(三):__str__()和__repr__()
使用python的魔法方法和time模块定制一个计时器的类 1.用time模块里的localtime()方法获取时间2.time.localtime返回struct_time格式3.表现你的类:__s ...
- 浅谈ThreadLocal模式
一.前言: ThreadLocal模式,严格意义上不是一种设计模式,而是java中解决多线程数据共享问题的一个方案.ThreadLocal类是java JDK中提供的一个类,用来解决线程安全问题,并不 ...
- LeetCode 136 Single Number 数组中除一个数外其他数都出现两次,找出只出现一次的数
Given an array of integers, every element appears twice except for one. Find that single one. class ...
- Java文件与io——RandomAccessFile
RandomAccessFile是IO包的类,从Object直接继承而来.只可以对文件进行操作,可以对文件进行读取和写入.RandomAccessFile有强大的文件读写功能,其内部是大型byte[] ...
- xmanger图形化登陆远程服务器
由于网上的资料比较杂,经过本人整理实际操作验证,保证ok 本人的服务器系统为centos5.8 下面的都是centos服务器上的操作,需要简单的配置下: win客户端使用xmanger软件:首先是服 ...
- 命名空间namespace、smarty使用(视图分离,MVC)、smarty模板语法、smarty缓存、MVC模式
一.命名空间:namespace 命名空间 可以理解为逻辑上的使用,为了防止重名 namespace :关键字 加载:require_once();//加载一次 include_once() 申明命名 ...
- mysql用户常见操作
一, 创建用户: 命令:CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 说明:username - 你将创建的用户名, host - 指 ...