promise内部实现原理:

function $Promise(fn) {
// Promise 的三种状态
this.PENDING = 'pending'
this.RESOLVED = 'resolved'
this.REJECTED = 'rejected' this.onResolvedCallback = [] // 成功回调队列
this.onRejectedCallback = [] // 失败回调队列
this.status = this.PENDING // 初始状态 // 成功函数处理
const resove = (val) => {
if (val instanceof $Promise) {
return value.then(resolve, reject)
}
this.triggerResolve(val)
}
// 失败函数处理
const reject = (val) => {
this.triggerReject(val)
} try {
// 初始同步执行
fn(resove, reject)
} catch (err) {
this.triggerReject(err)
}
} $Promise.prototype = {
then(onResolved, onRejected) {
// then参数不为函数则使用空函数,缺省函数返回当前值是为了 .then().then() 场景调用
onResolved = typeof onResolved === 'function' ? onResolved : function (value) { return value }
onRejected = typeof onRejected === 'function' ? onRejected : function (reason) { return reason } // Promise的then方法返回的是新的Promise对象,状态不会更改
return new $Promise((resolve, reject) => {
// 成功回调事件处理
const resolveHandle = val => {
let res = onResolved(val)
if (res instanceof $Promise) {
res.then(resolve, reject)
} else {
resolve(res)
}
}
// 失败回调事件处理
const rejectHandle = val => {
const res = onRejected(val)
if (res instanceof $Promise) {
res.then(resolve, reject)
} else {
reject(res)
}
}
// 当状态已经确认则立即执行
if (this.status === this.RESOLVED) {
return resolveHandle(this.value)
}
if (this.status === this.REJECTED) {
return rejectHandle(this.value)
}
// 当当前状态没有确认,则将回调函数放入队列,等待确认后再一次执行
this.onResolvedCallback.push(resolveHandle)
this.onRejectedCallback.push(rejectHandle)
})
},
// 状态确认后,成功回调队列的函数依次执行
triggerResolve(val) {
let _this = this
setTimeout(() => {
_this.value = val
if (_this.status === _this.PENDING) {
_this.status = _this.RESOLVED
_this.onResolvedCallback.forEach(it => {
it(val)
})
}
})
},
// 状态确认后,失败回调队列的函数依次执行
triggerReject(val) {
let _this = this
setTimeout(() => {
_this.value = val
if (_this.status === _this.PENDING) {
_this.status = _this.REJECTED
_this.onRejectedCallback.forEach(it => {
it(val)
})
}
})
},
// 最后捕捉调用链错误
catch(onRejected) {
return this.then(null, onRejected)
},
// finally实现,不管成功还是失败,都执行
finally(callback) {
return this.then((value) => {
return $Promise.resolve(callback()).then(() => value);
}, (err) => {
return $Promise.resolve(callback()).then(() => err);
});
}
}
// 单独调用Promise.resolve方法实现
$Promise.resolve = val => {
return new $Promise((resolve) => {
resolve(val)
})
}
// 单独调用Promise.reject方法实现
$Promise.reject = val => {
return new $Promise((resolve, reject) => {
reject(val)
})
}
// race函数的实现,返回结果最先完成
$Promise.race = values => {
return new $Promise((resolve, reject) => {
let len = values.length
if (!len) return
for (let i = 0; i < len; i++) {
values[i].then(res => {
resolve(res)
}, error => {
reject(error)
})
}
})
}
// all函数实现,如有错误立即返回,没有错误,等待全部完成再返回
$Promise.all = values => {
return new $Promise((resolve, reject) => {
let len = values.length
if (!len) return
let resolves = []
let nums = 0
function processValue(i, val) {
resolves[i] = val
if (++nums === len) {
resolve(resolves)
}
}
for (let i = 0; i < len; i++) {
values[i].then(res => {
processValue(i, res)
}, error => {
reject(error)
})
}
})
}
 

Promise内部实现原理的更多相关文章

  1. Mininet的内部实现原理简介

    原文发表在我的博客主页,转载请注明出处. 前言 之前模拟仿真网络一直用的是Mininet,包括写了一些关于Mininet安装,和真实网络相连接,Mininet简历拓扑的博客,但是大多数都是局限于具体步 ...

  2. KVO内部实现原理

    KVO的原理: 只要给一个对象注册一个监听, 那么在运行时, 系统就会自动给该对象生成一个子类对象, (格式如:NSKVONotifying_className), 并且重写自动生成的子类对象的被监听 ...

  3. Angular单页应用&AngularJS内部实现原理

    回顾 自定义指令 登录后获取登录信息session 首先在登录验证的时候保存一个user 在学生管理页面中运用ajax调用获取到登录的用户信息 对注销按钮添加点击事件:调用ajax在表现层给user赋 ...

  4. 8. 理解ZooKeeper的内部工作原理

    到目前为止,我们已经讨论了ZooKeeper服务的基础知识,并详细了解了数据模型及其属性. 我们也熟悉了ZooKeeper 监视(watch)的概念,监视就是在ZooKeeper命名空间中的znode ...

  5. Redis有序集内部实现原理分析(二)

    Redis技术交流群481804090 Redis:https://github.com/zwjlpeng/Redis_Deep_Read 本篇博文紧随上篇Redis有序集内部实现原理分析,在这篇博文 ...

  6. Apache Lucene评分机制的内部工作原理

    Apache Lucene评分机制的内部工作原理' 第5章

  7. Flask源码分析二:路由内部实现原理

    前言 Flask是目前为止我最喜欢的一个Python Web框架了,为了更好的掌握其内部实现机制,这两天准备学习下Flask的源码,将由浅入深跟大家分享下,其中Flask版本为1.1.1. 上次了解了 ...

  8. 4000余字为你讲透Codis内部工作原理

    一.引言 Codis是一个分布式 Redis 解决方案,可以管理数量巨大的Redis节点.个推作为专业的第三方推送服务商,多年来专注于为开发者提供高效稳定的消息推送服务.每天通过个推平台下发的消息数量 ...

  9. 《转》从系统和代码实现角度解析TensorFlow的内部实现原理 | 深度

    from https://www.leiphone.com/news/201702/n0uj58iHaNpW9RJG.html?viewType=weixin 摘要 2015年11月9日,Google ...

随机推荐

  1. Python:求时间差(天时分秒格式)

    传入一个时间戳,以天时分秒格式打印出时间差 输入一个10位的时间戳,求出时间差 def time_diff(timestamp): onlineTime = datetime.datetime.fro ...

  2. python自学Day07(自学书籍python编程从入门到实践)

    第8章 函数 函数是带名字的代码块,用于完成具体的工作. 学习定义函数,向函数传递信息. 学习如何编写主要任务是显示信息的函数,还有用于处理数据并返回一个或一组值得函数. 学习如何将函数存储在被称为模 ...

  3. 温故知新-多线程-Cache Line存在验证

    文章目录 简述 缓存行Cache Line 验证CacehLine存在? 参考 你的鼓励也是我创作的动力 Posted by 微博@Yangsc_o 原创文章,版权声明:自由转载-非商用-非衍生-保持 ...

  4. go 语言中windows Linux 交叉编译

    记录一下. 在windows系统编译,然后再Linux系统运行. 在项目目录下运行: 命令: set GOARM=5 set GOARCH=arm set GOOS=linux go build xx ...

  5. EIGRP-13-弥散更新算法-停滞在活动状态

    如果一台路由器参与到了针对某个目的地的弥散计算中(即将相应路由置为活动状态,并发送查询包),它必须首先等待所有邻居都返回响应包,之后它才能执行自已的弥散计算,接着选出新的最优路径,最后开始发送自已的响 ...

  6. 【漏洞复现】Fastjson <=1.2.47远程命令执行

      0x01 漏洞概述 漏洞描述 Fastjson是一款开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBe ...

  7. dB是乘以10还是乘以20

    dB即分贝(decibel),经常用来表示信号的大小.然而,今天在学习计算机网络的时候发现分贝的公式有两种:10lg(X) 或者 20lg(X) 很迷惑所以查找资料.得到的结果是dB在表示功率的时候用 ...

  8. python基础内容整理(一)

    基本数据类型 字符串 String 字符串是不可变类型 字符串的分割: s.split(sep)以给定的sep为分隔符对s进行分割. In [4]: s = "hello world&quo ...

  9. el-checkbox实现全选与单选

    实现目的:实现全选与多选,点击确定的时候获取每个值的id传给后台 1.HTML <el-checkbox v-model="checkAll" @change="h ...

  10. 说说TCP的三次握手和四次挥手

    一.传输控制协议TCP简介 1.1 简介 TCP(Transmission Control Protocol) 传输控制协议,是一种 面向连接的.可靠的.基于字节流的传输层 通信协议. TCP是一种面 ...