一会儿就要回家过年了,再来手写一个promise吧,要不等着下班真的煎熬。。。

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="author" content="杨欣">
<title>手写promise</title>
</head> <body> <script>
// 第一版
// class _Promise {
// constructor(handler) {
// // 判断参数是否不为函数
// if (typeof handler !== 'function') {
// throw new TypeError(`${handler} is not a function`)
// }
// this.state = 'pending'//初始状态
// this.value = null//最终返回值
// this.reason = null //失败原因
// let _this = this;
// const resolve = function (value) {
// if (_this.state === 'pending') {
// _this.state = 'fulfilled'//改变状态
// _this.value = value//最终返回值赋值
// console.log(_this.value)
// }
// }
// const reject = function (reason) {
// if (_this.state === 'pending') {
// _this.state = 'rejected'//改变状态
// _this.reason = reason//失败原因赋值
// }
// }
// handler(resolve, reject)
// }
// }
// new _Promise((resolve, reject) => {
// resolve(12345)
// }) // // 第二版 代码优化,加then方法,模拟异步操作
// class _Promise {
// constructor(handler) {
// // 判断参数是否不为函数
// if (typeof handler !== 'function') {
// throw new TypeError(`${handler} is not a function`)
// }
// this.initValue()//初始化值
// this.bindThis()//绑定this // handler(this.resolve, this.reject)
// }
// bindThis() {
// this.resolve = this.resolve.bind(this)
// this.reject = this.reject.bind(this)
// }
// initValue() {
// this.state = 'pending'//初始状态
// this.value = null//最终返回值
// this.reason = null //失败原因
// }
// resolve(value) {
// if (this.state === 'pending') {
// this.state = 'fulfilled'//改变状态
// this.value = value//最终返回值赋值
// }
// }
// reject(reason) {
// if (this.state === 'pending') {
// this.state = 'rejected'//改变状态
// this.reason = reason//失败原因赋值
// }
// } // then(onFulfilled, onRejected) {
// if (typeof onFulfilled !== 'function') {
// onFulfilled = function (value) {
// return value
// }
// } // if (typeof onRejected !== 'function') {
// onRejected = function (reason) {
// throw reason
// }
// } // if (this.state === 'fulfilled') {
// // 模拟异步
// setTimeout(() => {
// onFulfilled(this.value)
// }, 1000);
// } // if (this.state === 'reject') {
// setTimeout(() => {
// onRejected(this.reason)
// }, 1000);
// }
// }
// }
// new _Promise((resolve, reject) => {
// resolve(1234567)
// }).then((value) => {
// console.log(value, 'value')
// })
// new _Promise((resolve, reject) => {
// setTimeout(() => {
// resolve(1234567)
// }, 1000);
// }).then((value) => {
// console.log(value, 'value')
// })//这种情况下then方法中代码不会打印,因为then方法中state为pending,因此需要添加一个状态判断 // 第三版 添加状态判断,添加链式调用(then方法需要返回promise对象)
class _Promise {
constructor(handler) {
// 判断参数是否不为函数
if (typeof handler !== 'function') {
throw new TypeError(`${handler} is not a function`)
}
this.initValue()//初始化值
this.bindThis()//绑定this try {
handler(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
}
bindThis() {
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
}
initValue() {
this.state = 'pending'//初始状态
this.value = null//最终返回值
this.reason = null //失败原因
this.onFulfilledCbs = []//成功回调
this.onRejectedCbs = []//失败回调
}
resolve(value) {
if (this.state === 'pending') {
this.state = 'fulfilled'//改变状态
this.value = value//最终返回值赋值
// resolve成功执行
this.onFulfilledCbs.forEach(fn => fn(this.value))
}
}
reject(reason) {
if (this.state === 'pending') {
this.state = 'rejected'//改变状态
this.reason = reason//失败原因赋值
this.onRejectedCbs.forEach(fn => fn(this.reason))
}
} then(onFulfilled, onRejected) {
if (typeof onFulfilled !== 'function') {
onFulfilled = function (value) {
return value
}
} if (typeof onRejected !== 'function') {
onRejected = function (reason) {
throw reason
}
} if (this.state === 'fulfilled') {
// 模拟异步
setTimeout(() => {
onFulfilled(this.value)
});
} if (this.state === 'reject') {
setTimeout(() => {
onRejected(this.reason)
});
} let promise2 = new _Promise((resolve, reject) => {
if (this.state === 'fulfilled') {
setTimeout(() => {
try {
const data = onFulfilled(this.value)
_Promise.resolvePromise(promise2, data, resolve, reject)
} catch (e) {
reject(e)
}
})
} if (this.state === 'rejected') {
setTimeout(() => {
try {
const data = onRejected(this.reason)
_Promise.resolvePromise(promise2, data, resolve, reject)
} catch (e) {
reject(e)
}
})
} if (this.state === 'pending') {
this.onFulfilledCbs.push(value => {
setTimeout(() => {
try {
const data = onFulfilled(value)
_Promise.resolvePromise(promise2, data, resolve, reject)
} catch (e) {
reject(e)
}
})
}) this.onRejectedCbs.push(reason => {
setTimeout(() => {
try {
const data = onRejected(this.reason)
_Promise.resolvePromise(promise2, data, resolve, reject)
} catch (e) {
reject(e)
}
})
})
}
})
return promise2
}
}
_Promise.resolvePromise = function (promise2, data, resolve, reject) {
// data 与 promise 相等
if (promise2 === data) {
reject(new TypeError('Chaining cycle detected for promise'))
} let flag = false
if (data instanceof _Promise) {
// 判断 data 为 Promise
data.then(
value => {
_Promise.resolvePromise(promise2, value, resolve, reject)
},
reason => {
reject(reason)
}
)
} else if (data !== null && (typeof data === 'object' || typeof data === 'function')) {
// data 为对象或函数
try {
const then = data.then
if (typeof then === 'function') {
then.call(
data,
value => {
if (flag) return
flag = true
_Promise.resolvePromise(promise2, value, resolve, reject)
},
reason => {
if (flag) return
flag = true
reject(reason)
}
)
} else {
if (flag) return
flag = true
resolve(data)
}
} catch (e) {
if (flag) return
flag = true
reject(e)
}
} else {
resolve(data)
}
} new _Promise((resolve, reject) => {
setTimeout(() => {
resolve(1234567)
}, 1000);
}).then((value) => {
console.log(value, 'value')
return 11111
}, (reason) => {
console.log(reason, 'reason')
}).then((res) => {
console.log(res, 'res')
}) </script>
</body> </html>

最新文章

  1. 再看 AspriseOCR - OCR应用开发 -20151124
  2. 隐式意图Intent
  3. boa移植
  4. 创建Google网站地图Sitemap.xml
  5. Maven打jar发布包的常用配置
  6. Linux命令(17)du 查看文件和目录磁盘使用情况
  7. oracle 文件导出
  8. Json(2)-DataContractJsonSerializer
  9. 关于Firefox浏览器如何支持ActiveX控件,一个小的Hellow World
  10. PostgreSQL的 create index concurrently
  11. Androida规划nt打包
  12. why TCP guarentee delivery?
  13. C#变量、常量、枚举、预处理器指令知多少
  14. springBoot系列教程01:elasticsearch的集成及使用
  15. 解决 RabbitMQ 集群 Channel shutdown: connection error 错误(HAProxy 负载均衡)
  16. 内核调试打印dump_stack
  17. hadoop mapreduce 基础实例一记词
  18. Spark Streaming 002 统计单词的例子
  19. 插入排序的Java代码实现
  20. Hybris阶段总结(2)hybris架构

热门文章

  1. Python项目1:自动添加标签
  2. Java基础 之三 继承
  3. 机器学习3《数据集与k-近邻算法》
  4. Java POI 导出带有图片的word
  5. centos搭建dns服务
  6. 一些 git 常用的命令
  7. 【鸿蒙开发板试用报告】用OLED板实现FlappyBird小游戏(上)
  8. java开发两年!这些异常处理的方式你得知道,不然你凭什么涨薪!
  9. 如何调整MathType公式的字体大小
  10. MathType中如何编辑求和公式