1 Star 0 Fork 0

wattmelon/studyNotes

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
promise.js 5.59 KB
一键复制 编辑 原始数据 按行查看 历史
wattmelon 提交于 2020-09-15 19:58 . 移动位置
class Promise {
// 接收函数参数executor
constructor(executor) {
// 参数校验
if (typeof executor !== 'function') {
throw new TypeError(`Promise resolver ${executor} is not a function`)
}
this.initValue()
this.initBind()
// try...catch捕获错误,交给reject
try {
// 传递给executor并执行
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// 初始化值
initValue() {
this.value = null // 终值
this.reason = null // 拒因
this.state = Promise.PENDING // 状态(不可逆)
this.onFulfilledCallbacks = [] // 成功回调
this.onRejectedCallbacks = [] // 失败回调
}
/*
调用resovle/reject时是匿名调用,此时this=undefined
1. 使用箭头函数
2. bind绑定
*/
// 绑定this
initBind() {
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
}
// 定义resolve
resolve(value) {
// 成功后的一系列操作(状态改变,成功回调的执行)
if (this.state === Promise.PENDING) {
this.state = Promise.FULFILLED
this.value = value
this.onFulfilledCallbacks.forEach(fn => fn(this.value))
}
}
// 定义reject
reject(reason) {
// 失败后的一系列操作(状态改变,失败回调的执行)
if (this.state === Promise.PENDING) {
this.state = Promise.REJECTD
this.reason = reason
this.onRejectedCallbacks.forEach(fn => fn(this.reason))
}
}
// 定义then
then(onFulfilled, onRejected) {
// 参数校验 不是函数->穿透效果(连续调用then)
if (typeof onFulfilled !== 'function') {
onFulfilled = function (value) {
return value
}
}
if (typeof onRejected !== 'function') {
onRejected = function (reason) {
throw reason
}
}
// 实现链式调用,且改变后面then的值,必须通过新的实例
let promise2 = new Promise((resolve, reject) => {
if (this.state === Promise.FULFILLED) {
// setTimeout模拟异步
setTimeout(() => {
try {
const x = onFulfilled(this.value)
Promise.resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
}
if (this.state === Promise.REJECTD) {
setTimeout(() => {
try {
const x = onRejected(this.reason)
Promise.resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
}
if (this.state === Promise.PENDING) {
this.onFulfilledCallbacks.push((value) => {
setTimeout(() => {
try {
const x = onFulfilled(this.value)
Promise.resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
})
this.onRejectedCallbacks.push((reason) => {
setTimeout(() => {
try {
const x = onRejected(this.reason)
Promise.resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
})
}
})
return promise2
}
}
Promise.PENDING = 'pending'
Promise.FULFILLED = 'fulfilled'
Promise.REJECTD = 'rejected'
Promise.resolvePromise = function (promise2, x, resolve, reject) {
// x 与 Promise 相等
if (promise2 === x) {
// 避免循环调用
reject(new TypeError('Chaining cycle detected for promise'))
}
// 定义变量,是否被调用过
let called = false
if (x instanceof Promise) {
// x 是 Promise
x.then(value => {
Promise.resolvePromise(promise2, value, resolve, reject)
}, reason => {
reject(reason)
})
} else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
// x 是 对象或函数
try {
const then = x.then
if (typeof then === 'function') {
then.call(x, (value) => {
if (called) return
called = true
Promise.resolvePromise(promise2, value, resolve, reject)
}, reason => {
if (called) return
called = true
reject(reason)
})
} else {
if (called) return
called = true
resolve(x)
}
} catch (e) {
if (called) return
called = true
reject(e)
}
} else {
// 普通值
resolve(x)
}
}
// 测试Promise
// 语法糖
Promise.defer = Promise.deferred = function () {
let dfd = {}
dfd.promise = new Promise((resolve, reject) => {
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
}
module.exports = Promise;
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/xuzichang/studyNotes.git
git@gitee.com:xuzichang/studyNotes.git
xuzichang
studyNotes
studyNotes
master

搜索帮助