promise实现
2021-12-04 本文已影响0人
storyWrite
/*
* @Author: dezhao.zhao@hand-china.com
* @Date: 2021-11-23 15:37:06
* @Description:
*/
// 定义状态常量
const PENDING = 'pending',
FULFILLED = 'fulfilled',
REJECTE = 'reject'
function MyPromise(executor) {
const self = this // 缓存promise对象
// 初始执行 状态为pending
self.status = PENDING
// 成功回调
self.onResolveCb = []
// 失败回调
self.onRejectedCb = []
// 成功执行函数
function resolve(value) {
// 如果promise 返回值为一个promise 则执行zhen 方法并传入resolve与reject函数
if (value instanceof MyPromise) {
return value.then(resolve, reject)
}
// 只有等待态调用该函数,状态才会转为成功态
if (self.status === PENDING) {
self.status = FULFILLED
// 成功后获得值,不可修改
self.value = value
// 调用所有成功回调
self.onResolveCb.forEach((cb) => cb(value))
}
}
function reject(reason) {
// 只有等待态调用该函数,状态转为失败态
if (self.status === PENDING) {
self.status = REJECTE
// 失败后获得值,不可修改
self.value = reason
// 调用所有失败回调
self.onRejectedCb.forEach((cb) => cb(reason))
}
}
try {
// 函数执行可能报错,报错则需要reject
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
MyPromise.prototype.then = function (onFulFilled, onRejected) {
// 如果没有传成功回调函数,则赋值一个默认函数
onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : (value) => value
onRejected =
typeof onRejected === 'function'
? onRejected
: (reason) => {
throw new e(reason)
}
let self = this
let promise2
if (self.status === FULFILLED) {
console.log('then fulfilled')
return (promise2 = new MyPromise((resolve, reject) => {
// 所有成功与失败设置为异步,下一个事件循环执行,保证用户excutor中的代码先执行完成然后再执行onFulfilled回调
setTimeout(() => {
try {
let x = onFulFilled(self.value)
// 解析then中返回的promise
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
}))
}
if (self.status === REJECTE) {
promise2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
try {
let x = onRejected(self.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
})
return promise2
}
if (self.status === PENDING) {
console.log('then pending')
// pending状态添加成功回调
self.onResolveCb.push(() => {
return (promise2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
try {
let x = onFulFilled(self.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
}))
})
// pending状态添加失败回调
self.onRejectedCb.push(() => {
return (promise2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
try {
let x = onRejected(self.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
}))
})
}
}
function resolvePromise(promise2, x, resolve, reject) {
// let p2 = p1.then(() => p2)
console.log('resolve Promise')
let called = false
if (promise2 === x) {
return reject(new Typee('循环引用'))
}
if (x instanceof MyPromise) {
if (x.status === PENDING) {
x.then(function (y) {
resolvePromise(promise2, y, resolve, reject)
}, reject)
} else {
x.then(resolve, reject)
}
// thenable Object 有then方法的对象或者方法
} else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
// 当then为get属性的时候,可以设置抛出异常
try {
console.log('应该执行到这里', typeof x.then === 'function')
let then = x.then
if (typeof then === 'function') {
then.call(
function () {
console.log('执行到here')
if (called) return
called = true
resolvePromise(promise2, x, resolve, reject)
},
function (e) {
if (called) return
called = true
reject(e)
}
)
} else {
// 到此表示x.then 不存在 或者不是一个函数
resolve(x)
}
} catch (e) {}
// 字符串或其他基本数据
} else {
if (called) return
called = true
resolve(x)
}
}
MyPromise.prototype.catch = function (onRejected) {
this.then(null, onRejected)
}
MyPromise.deferred = MyPromise.defer = function () {
let defer = {}
defer.promise = new MyPromise(function (resolve, reject) {
defer.resolve = resolve
defer.reject = reject
})
return defer
}
MyPromise.all = function (promises) {
return new MyPromise((resolve, reject) => {
const result = []
// count 不能定义在done里面 不然每次都会初始化为0,计数错误
let count = 0
function done(index) {
return function (data) {
result[index] = data
if (++count === promises.length) {
resolve(result)
}
}
}
promises.forEach((promise, index) => {
promise.then(done(index), reject)
})
})
}
MyPromise.race = function (promises) {
return new MyPromise((resolve, reject) => {
promises.forEach((promises) => {
promises.then(resolve, reject)
})
})
}
MyPromise.resolve = function (value) {
return new MyPromise((resolve) => resolve(value))
}
MyPromise.reject = function (reason) {
return new MyPromise(resolve, (reject) => reject(reason))
}
/**
* 2
*/
// const ps = [
// new MyPromise((resolve, reject) => {
// resolve(122)
// setTimeout(() => {
// reject(1)
// }, 1000)
// }),
// new MyPromise((resolve, reject) => {
// setTimeout(() => {
// resolve(2)
// }, 1000)
// })
// ]
// const p1 = MyPromise.race(ps).then(
// (data) => {
// console.log('data', data)
// },
// (err) => {
// console.log('err', err)
// }
// )
/**
* 1.
*/
// const p1 = new MyPromise((resolve, reject) => {
// const num = Math.random()
// if (num > 0.5) {
// console.log('222')
// resolve(23323)
// setTimeout(() => {
// resolve(num)
// }, 1000)
// } else {
// reject(num)
// }
// })
// // const p2 = p1.then();
// let p2 = p1.then(
// (data) => {
// console.log('data', data)
// // return p2
// },
// (err) => {
// console.log('err', err)
// // return p2
// }
// )
// p2.then(
// (data) => {
// console.log('p2 data', data)
// },
// (err) => {
// console.log('p2 err', err)
// }
// )
const pr1 = new MyPromise((resolve) => {
resolve(100)
})
const pr2 = pr1.then((data) => {
console.log('datapro1', data)
return new Promise((resolve) => {
resolve(data)
})
})
pr2.then((data) => console.log('datapro2', data))