一步一步实现一个Promise A+规范的 Promise
var fn = new Promise(function (resolve, reject) {
// 异步操作
setTimeout(function() {
resolve('resolve 01')
// 由于reslove和 reject 是互斥的,因为已经调用了 resolve,这里reject不会执行
reject('reject 01')
}, 500)
})
fn().then(function (data) {
console.log('成功1:', data)
return new Promise(function (resolve, reject) {
reject('reject 02')
}
)}, function (err) {
console.log('失败1:', err)
})
.then(function (data) {
console.log('成功2:', data)
}, function (err) {
console.log('失败2:', err)
}).then(function (data) {
console.log('成功2:', data)}, function (err) {
console.log('失败2:', err)
})
结果:

可以看到,Promise 通常会有这些特性:
一,Promise 类的实现
var Promise = function (executor) {
console.log('证明不是用的原生 Promise')
var _this = this
this.status = 'pending'
// 默认状态,可以转化为 resolved 和 rejected
this.successVal = undefined
this.failVal = undefined
// 执行了成功或失败后,要将状态对应修改成成功和失败
function resolve (val) {
if ( _this.status === 'pending' ) {
_this.status = 'resolved'
_this.successVal = val
}
}
function reject (val) {
if ( _this.status === 'pending' ) {
_this.status = 'rejected'
_this.failVal = val
}
}
try {
// 应该还记得,Promise 的参数是一个函数吧,我们称之为 executor(执行器)
// 同时这个函数接收2个参数,分别是成功和失败的回调函数
executor(resolve, reject)
} catch (e) {
// 如果发生异常,直接reject捕获
reject(e)
}
}
// then 方法接收2个参数,分别是成功和失败的回调函数
Promise.prototype.then = function (onFulfilled, onRejected) {
var _this = this
// 显然要根据当前状态来执行成功或失败的回调了
if ( _this.status === 'resolved' ) {
onFulfilled(_this.successVal)
}
if ( _this.status === 'rejected' ) {
onFulfilled(_this.failVal)
}
}
var fn = new Promise(function (resolve, reject) {
resolve('oooook~')
})
fn.then(function (data) {
console.log('success: ', data)}, function (err) {
console.log('err: ', err)
})
结果:

结果看上去很美。但如果改成下面这样呢?
var fn = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('oooook~')
}, 500)
})
fn.then(function (data) {
console.log('success: ', data)
}, function (err) {
console.log('err: ', err)
})
结果:

var Promise = function (executor) {
console.log('证明不是用的原生 Promise 的一句废话')
var _this = this this.status = 'pending'
// 默认状态,可以转化为 resolved 和 rejected
this.successVal = undefined
this.failVal = undefined
// ----------------- 表示新增代码 -------------------- // 用于存放成功和失败的回调
this.onFulfilledList = []
this.onRejectedList = []
function resolve (val) {
if ( _this.status === 'pending' ) {
_this.status = 'resolved'
_this.successVal = val
// -------------- 执行所有的成功回调 ---------------
_this.onFulfilledList.forEach(function(fn){
fn()
})
}
}
function reject (val) {
if ( _this.status === 'pending' ) {
_this.status = 'rejected'
_this.failVal = val
// -------------- 执行所有的失败回调 ---------------
_this.onRejectedList.forEach(function(fn){
fn()
})
}
}
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onFulfilled, onRejected) {
var _this = this
if ( _this.status === 'resolved' ) {
onFulfilled(_this.successVal)
}
if ( _this.status === 'rejected' ) {
onFulfilled(_this.failVal)
}
// ----------------- 对异步调用的处理 -------------------
// 说明:如果是异步调用,走到 then 方法里的时候,status 还没有被修改,仍然
// 是 pending 状态,所以这时候需要再回去执行 executor 里的对应方法,而对应的
// 方法会将对应的存放回调的 list 里的方法执行(类似发布-订阅模式一样的处理)
if ( _this.status === 'pending' ) {
_this.onFulfilledList.push(function () {
onFulfilled(_this.successVal)
})
_this.onRejectedList.push(function () {
onRejected(_this.failVal)
})
}
}
看看效果:
一步一步实现一个Promise A+规范的 Promise的更多相关文章
- 手写一款符合Promise/A+规范的Promise
手写一款符合Promise/A+规范的Promise 长篇预警!有点长,可以选择性观看.如果对Promise源码不是很清楚,还是推荐从头看,相信你认真从头看到尾,并且去实际操作了,肯定会有收获的.主要 ...
- 手写符合Promise/A+规范的Promise
const PENDING = "pending"; const RESOLVED = "resolved"; const REJECTED = "r ...
- 手写基于Promise A+规范的Promise
const PENDING = 'pending';//初始态const FULFILLED = 'fulfilled';//初始态const REJECTED = 'rejected';//初始态f ...
- 按照 Promise/A+ 规范逐行注释并实现 Promise
0. 前言 面试官:「你写个 Promise 吧.」 我:「对不起,打扰了,再见!」 现在前端越来越卷,不会手写 Promise 都不好意思面试了(手动狗头.jpg).虽然没多少人会在业务中用自己实现 ...
- Promise原理—一步一步实现一个Promise
promise特点 一个promise的当前状态只能是pending.fulfilled和rejected三种之一.状态改变只能是pending到fulfilled或者pending到rejected ...
- 剖析Promise内部结构,一步一步实现一个完整的、能通过所有Test case的Promise类
本文写给有一定Promise使用经验的人,如果你还没有使用过Promise,这篇文章可能不适合你,建议先了解Promise的使用 Promise标准解读 1.只有一个then方法,没有catch,ra ...
- 教你一步一步实现一个Promise
Promise我想现在大家都非常熟悉了,主要作用就是解决异步回调问题,这里简单介绍下. Promise规范是CommonJS规范之一,而Promise规范又分了好多种,比如 Promises/A.Pr ...
- 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑
阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...
- 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成
阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...
随机推荐
- HDU3085NightmareII题解--双向BFS
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3085 分析 大意就是一个男孩和一个女孩在网格里,同时还有两个鬼,男孩每轮走三步,女孩每轮走一步,与鬼曼 ...
- CSS3总结四:盒模型(box)
盒模型:标准盒模型.混杂盒模型 什么时候会触发混杂模式? 为什么要混杂模式渲染规则盒模型? box-sizing:content-box.border-box 关于盒模型的一些其他样式和属性值 一.盒 ...
- js多语言切换demo
网站为了国际化的需要,会使用到语言包,案例如下图. 这次尝试用js来打语言包,用到了插件 jquery.i18n.properties ,很明显,使用这个插件需要先加载jquery. 代码布局结构 ...
- element-ui中点击菜单,改变当前菜单背景颜色
需求: vue项目中,点击左侧菜单,tags页显示当前打开的菜单,并且高亮显示当前菜单 实现效果: 实现代码:在vuex里面定义tags存放所有打开的菜单,和当前打开的索引curtagsIndex:, ...
- 【异常】Caused by: org.apache.phoenix.coprocessor.HashJoinCacheNotFoundException:
1 详细异常 Caused by: org.apache.phoenix.coprocessor.HashJoinCacheNotFoundException: ERROR 900 (HJ01): H ...
- STM32定义变量位于指定的SRAM地址
1.定义一个数组比如value[],让数组的首地址指向特定的SRAM地址,比如0x20000100 1)__align(8) uint8_t value[20] __attribute__((at(0 ...
- Oracle 触发器学习笔记一
触发器名:触发器对象的名称.由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途.触发时间:指明触发器何时执行,该值可取:before:表示在数据库动作之前触发器执行;after:表示 ...
- 第十五届四川省省赛 SCU - 4443 Range Query
先给你1~N的N个数 再给你每种最多50个的条件(ai,bi,ci) 或者[ai,bi,ci] (ai,bi,ci)表示下标ai到bi的最小值必为ci [ai,bi,ci]表示下标ai到bi的最大值必 ...
- Mybatis mapper.xml 配置
<!-- xml的标准格式 --><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE ...
- Python 读写XML文件
Python 生成XML文件 from xml.dom import minidom # 生成XML文件方式 def generateXml(): impl = minidom.getDOMImple ...

