参考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的更多相关文章

  1. 【原】手写一个promise

    上一篇文章中,我们介绍了Promise的基本使用,在这篇文章中,我们试着自己来写一个Promise,主要是学习Promise的内部机制,学习它的编程思想. !!!备注:本文写的不好,仅供自己学习之用, ...

  2. 掘金转载-手写一个Promise

    目录 一 什么是Promise ? 二 Promises/A+ 规范 2.1 术语 2.2 基本要求 2.2.1. Promise的状态 2.2.2. Then 方法 2.3 简易版实践 2.4 进一 ...

  3. 手写一个Promise/A+,完美通过官方872个测试用例

    前段时间我用两篇文章深入讲解了异步的概念和Event Loop的底层原理,然后还讲了一种自己实现异步的发布订阅模式: setTimeout和setImmediate到底谁先执行,本文让你彻底理解Eve ...

  4. 面试----你可以手写一个promise吗

    参考:https://www.jianshu.com/p/473cd754311f <!DOCTYPE html> <html> <head> <meta c ...

  5. 手写一个promise

    Promise A+ 规范:https://promisesaplus.com/ 注:以下代码没有通过 promises-aplus-tests 的全部测试,但基本功能还是全的( 测试结果: 864 ...

  6. 只会用就out了,手写一个符合规范的Promise

    Promise是什么 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可以获取异步操作的消息.Prom ...

  7. 一起学习造轮子(一):从零开始写一个符合Promises/A+规范的promise

    本文是一起学习造轮子系列的第一篇,本篇我们将从零开始写一个符合Promises/A+规范的promise,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Pr ...

  8. 请手写代码实现一个promise

    第一步:promise的声明 class Promise{ // 构造器 constructor(executor){ // 成功 let resolve = () => { }; // 失败 ...

  9. 操刀 requirejs,自己动手写一个

    前沿 写在文章的最前面 这篇文章讲的是,我怎么去写一个 requirejs . 去 github 上fork一下,顺便star~ requirejs,众所周知,是一个非常出名的js模块化工具,可以让你 ...

随机推荐

  1. php静态方法和属性

    静态方法和属性由static关键字定义 静态方法和属性不用实例化也可以直接访问,如 self::test(),self::tt 类实例化后可以访问静态方法,但是不可以访问静态属性 声明类属性或方法为静 ...

  2. day10函数作业详解

    1.day10题目 2,写函数,接收n个数字,求这些参数数字的和.(动态传参) 3,读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么? a=10 b=20 def test5(a,b): ...

  3. 如何使用JMETER从JSON响应中提取数据

    如果你在这里,可能是因为你需要使用JMeter从Json响应中提取变量. 好消息!您正在掌握掌握JMeter Json Extractor的权威指南.作为Rest API测试指南的补充,您将学习掌握J ...

  4. 关于强大的requests

    存到文件: with open(filename, 'wb') as fd: for chunk in r.iter_content(chunk_size): fd.write(chunk) 使用 R ...

  5. scrapy可视化管理工具spiderkeeper使用笔记

    http://www.scrapyd.cn/doc/156.html  入门中文教程 spiderkeeper是一款开源的spider管理工具,可以方便的进行爬虫的启动,暂停,定时,同时可以查看分布式 ...

  6. jvm 锁Lock

    自旋锁 线程想要获得一个对象的锁,如果没有得到,会继承占用CPU尝试获取锁, 线程不进入阻塞状态,仍然在Running 锁消除 public void lockTest() { String aa = ...

  7. vi 编辑器的复制

    v 进入可视化模式,y  复制选中区域,p粘贴 Ctrl + v 块模式 yy 复制当前行

  8. 【密码学】SSL双向认证以及证书的制作和使用

    客户端认证服务器: 正规的做法是:到国际知名的证书颁发机构,如VeriSign申请一本服务器证书,比如支付宝的首页,点击小锁的图标,可以看到支付宝是通过VeriSign认证颁发的服务器证书: 我们用的 ...

  9. prototype 以及 constructor 属性的理解

    1 为什么 xx.constructor.prototype 可以访问到当前对象的原型. 'str'.constructor.prototype      'str'.constructor 指向当前 ...

  10. Ionic 解决gradle下载慢的问题

    问题 使用Ioinc添加安卓平台或者编译的时候,提示gradle-XXX-all.zip下载,此进度缓慢. 解决 下载gradle对应的zip文件. 参考资源:http://services.grad ...