实现如果下规范的promise
Aplus规范
1,promise是一个类:有三个状态 pending/等待态 fulfilled/成功态 rejected/失败态
2,promise默认执行器立即执行
3,Promise的实例都有一个then方法
4,执行器中用户可以自己决定成功或者失败,并且传入成功或者失败的原因
5,如果excutor执行器函数发生异常的时候也会执行失败的逻辑
6,如果Promise一旦进入成功态就不能再变为失败态,反之亦然
 
// 定义promise三种状态
let PENDING = 'PENDING'
let RESOLVED = 'RESOLVED' // 成功状态
let REJECTED = 'REJECTED' // 失败状态
console.log('own') const resolvePromise = (promise2, x, resolve, reject) => {
// A+规范中 x和promise2引用同一个对象抛出类型错误
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
// 后续的条件要严格判断 保证代码能和别的库一起使用
// x可能是一个函数或者对象
if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
try {
let then = x.then;
if (typeof then === 'function') {
// 只能判断then是函数就认为其是promise
then.call(x, y => {
resolve(y)
}, e => {
reject(e)
})
} else {
resolve(x)
}
} catch (e) {
//TODO handle the exception
} } else {
resolve(x)
}
} class Promise {
constructor(excutor) {
this.status = PENDING
// 成功和失败的原因需要保存
this.value = undefined; // 成功的值
this.reason = undefined; // 失败的值
this.onResolvedCallbacks = []; // 存储成功的回调函数数组
this.onRejectedCallbacks = []; // 存储失败的回调函数数组
// 只有等待态的时候才能更改状态 let resolve = (value) => { if(value instanceof Promise){
value.then(resolve,reject) // 判断是promise.resolve 中如果传promise 递归解析 ,有延迟效果
} if (this.status = PENDING) {
this.value = value;
this.status = RESOLVED;
this.onResolvedCallbacks.forEach(fn => fn())
} }
let reject = (reason) => {
if (this.status = PENDING) {
this.reason = reason;
this.status = REJECTED;
this.onRejectedCallbacks.forEach(fn => fn())
}
}
// 当函数发生异常直接抛出错误
try {
excutor(resolve, reject)
} catch (e) {
reject(e)
}
}
// 关于then方法:
// 1: promise 成功或者失败会传递到外层的下一个then方法
// 2: 返回的是普通值(除了promise之外的值)都会触底到下一then的成功中;出错的情况走到下一次的失败中;
// 3: 错误处理 。自己最近的then没有错误处理,会向下传递错误直到有错误处理
// 4: 每次执行完then 返回都是新的promise (一旦成功或者失败就不能够修改状态)
then (onFulfilled, onRejected) { // 如果then中返回一个promise 我需要用x来决定是决定promise返回成功还是失败 let promise2 = new Promise((resolve, reject) => { // 链式调用
if (this.status === RESOLVED) {
setTimeout(() => { // 为了让resolvePromise拿到promise2
try {
// 如果状态是成功了,需要调用传入的第一个onFulfilled函数
let x = onFulfilled(this.value) //成功的回调直接执行;执行完成后拿到结果;ps: 成功之后返回的直接执行拿到结果存放到x中
// 但是返回的promise 还能继续then,继续传递成功的结果
// x可能是promise,解析promise ,使用这个返回的结果决定下一个then是成功还是失败
resolvePromise(promise2, x, resolve, reject) // 调用了下一个promise的resolve
} catch (error) {
reject(error)
} }, 0)
}
if (this.status === REJECTED) {
setTimeout(() => { // 为了让resolvePromise拿到promise2
try {
// 如果状态失败了,就需要使用第二个函数讲失败的原因返回
let x = onRejected(this.reason)
// 处理失败
resolvePromise(promise2, x, resolve, reject) //普通值都会传递到下一个的成功
} catch (error) {
reject(error)
} }, 0)
}
// 调用then的时候可能是pending状态
if (this.status === PENDING) {
this.onResolvedCallbacks.push(() => {
// todo
setTimeout(() => {
try {
let x = onFulfilled(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (error) {
reject(error)
}
}, 0) })
this.onRejectedCallbacks.push(() => {
// todo
setTimeout(() => {
try {
let x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0)
})
}
})
return promise2;
}
catch(errCallBack){
return this.then(null,errCallBack)
}
static resolve(data){
// 快速创建一个成功的promise
return new Promise((resolve,reject) => {
resolve(data)
})
}
static reject(reason){
// 快速创建一个失败的promise
return new Promise((resolve,reject) => {
reject(reason)
})
}
}

最新文章

  1. TODO:字节的那点事Go篇
  2. 带你走近AngularJS - 基本功能介绍
  3. 项目管理知识框架PMBOK(文字版)
  4. P264练习题1.2题
  5. ANT编译build.xml
  6. 亲测 asp.net 调用 webservice返回json
  7. IOS ScrollowView 滑动到边缘后不允许再拖动
  8. mysql允许远程IP访问
  9. 8.Spark SQL
  10. 改变UITableView选中行高亮的颜色
  11. JHipster简介
  12. Polar Code(1)关于Polar Code
  13. 开始Dev之路
  14. 《Linux内核设计与实现》读书笔记 3
  15. 用Synoptic Panel自定义基于图形的可视化控件--制作一张剧场售票统计报表
  16. [转]jquery设置select选中,赋值等操作
  17. U811.1接口EAI系列之三--采购订单生成--VB语言
  18. Apache POI – Reading and Writing Excel file in Java
  19. SSIS教程:创建简单的ETL包 -- 1. 创建项目和基本包
  20. 【BZOJ1564】【NOI2009】二叉查找树(动态规划)

热门文章

  1. .net为程序集签名之.pfx文件
  2. 网络编程 并发socketserver
  3. 海量数据分析更快、更稳、更准。GaussDB(for MySQL) HTAP只读分析特性详解
  4. sqlmap的使用手册
  5. luoguP6624 [省选联考 2020 A 卷] 作业题(莫比乌斯反演,矩阵树定理)
  6. 【Python 第1课】安装
  7. String--int互转
  8. 比较HQL、Criteria、Native-SQL这三者做查询的区别,以及应该如何进行选择?
  9. 在Spring框架中如何更有效地使用JDBC?
  10. MybatisPlus 多租户的常见问题