不多BB直接展示
<script>
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {
state = PENDING
result = undefined
#handlers = []
constructor(func) {
const resolve = (res) => {
if (this.state === PENDING) {
this.state = FULFILLED
this.result = res
this.#handlers.forEach((item) => {
item[0](res)
})
}
}
const reject = (err) => {
if (this.state === PENDING) {
this.state = REJECTED
this.result = err
this.#handlers.forEach((item) => {
item[1](err)
})
}
}
try {
func(resolve, reject)
} catch (err) {
reject(err)
}
}
then(onFulfilled, onRejected) {
// typeof
onFulfilled =
Object.prototype.toString.call(onFulfilled) === '[object Function]'
? onFulfilled
: (x) => x
onRejected =
typeof onRejected === 'function'
? onRejected
: (x) => {
throw x
}
const p2 = new MyPromise((rel, rej) => {
if (this.state === FULFILLED) {
runAsyncTask(() => {
try {
const x = onFulfilled(this.result)
resolvePromise(p2, x, rel, rej)
} catch (err) {
rej(err)
}
})
} else if (this.state === REJECTED) {
runAsyncTask(() => {
try {
const x = onRejected(this.result)
resolvePromise(p2, x, rel, rej)
} catch (err) {
rej(err)
}
})
} else if (this.state === PENDING) {
this.#handlers.push([
() => {
runAsyncTask(() => {
try {
const x = onFulfilled(this.result)
resolvePromise(p2, x, rel, rej)
} catch (err) {
rej(err)
}
})
},
() => {
runAsyncTask(() => {
try {
const x = onRejected(this.result)
resolvePromise(p2, x, rel, rej)
} catch (err) {
rej(err)
}
})
}
])
}
})
return p2
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
finally(onFinally) {
return this.then(onFinally, onFinally)
}
static resolve(val) {
if (val instanceof MyPromise) {
return val
}
return new MyPromise((res, rej) => {
res(val)
})
}
static reject(v) {
return new MyPromise((undefined, rej) => {
rej(v)
})
}
static race(promiseArr) {
return new MyPromise((reso, reje) => {
// 判断是不是数组(可迭代对象)
if (!promiseArr || !promiseArr[Symbol.iterator]) {
reje(new TypeError('Argument is not iterable'))
}
promiseArr.forEach((el) => {
MyPromise.resolve(el).then(
(res) => {
reso(res)
},
(err) => {
reje(err)
}
)
})
})
}
static all(promiseArr) {
return new MyPromise((reso, reje) => {
// if (!Array.isArray(promiseArr)) {
// reje(new TypeError('Argument is not iterable'))
// }
// 判断是不是数组(可迭代对象)
if (
!promiseArr ||
!(typeof promiseArr[Symbol.iterator] === 'function')
) {
reje(new TypeError('Argument is not iterable'))
}
// console.log('123'[Symbol.iterator])
// if (!promiseArr || !promiseArr[Symbol.iterator]) {
// }
promiseArr = Array.from(promiseArr)
// if (promiseArr.length === 0) {
// reso(promiseArr)
// }
promiseArr.length === 0 && reso(promiseArr)
const resArr = []
let count = 0
promiseArr.forEach((v, i) => {
MyPromise.resolve(v).then(
(res) => {
resArr[i] = res
count++
count === promiseArr.length && reso(resArr)
},
(err) => {
reje(err)
}
)
})
})
}
static allSettled(promiseArr) {
return new MyPromise((reso, reje) => {
// 判断是不是数组(可迭代对象)
if (promiseArr[Symbol.iterator] === undefined) {
reje(new TypeError('Argument is not iterable'))
}
promiseArr = Array.from(promiseArr)
// if (promiseArr.length === 0) {
// reso(promiseArr)
// }
promiseArr.length === 0 && reso(promiseArr)
const resArr = []
let count = 0
promiseArr.forEach((v, i) => {
MyPromise.resolve(v).then(
(res) => {
resArr[i] = { status: FULFILLED, value: res }
count++
count === promiseArr.length && reso(resArr)
},
(err) => {
resArr[i] = { status: REJECTED, reason: err }
count++
count === promiseArr.length && reso(resArr)
}
)
})
})
}
static any(promiseArr) {
return new MyPromise((reso, reje) => {
// 判断是不是数组(可迭代对象)
if (promiseArr[Symbol.iterator] === undefined) {
console.log(222)
reje(new TypeError('Argument is not iterable'))
}
promiseArr = Array.from(promiseArr)
// if (promiseArr.length === 0) {
// reso(promiseArr)
// }
promiseArr.length === 0 &&
reje(new AggregateError(promiseArr, '123456789'))
const errArr = []
let count = 0
promiseArr.forEach((v, i) => {
MyPromise.resolve(v).then(
(res) => {
reso(res)
},
(err) => {
errArr[i] = err
count++
count === promiseArr.length &&
reje(
new AggregateError(errArr, 'ALL Promise were rejected')
)
}
)
})
})
}
}
// 抽取函数
function resolvePromise(p2, x, rel, rej) {
if (x === p2) {
throw new TypeError(
'123Chaining cycle detected for promise #<Promise>'
)
}
if (x instanceof MyPromise) {
x.then(
(res) => {
rel(res)
},
(err) => {
rej(err)
}
)
} else {
rel(x)
}
}
// 封装一个异步执行函数
// 01. 自定义函数方式(命名函数)可以先调用在定义(变量提升)
// 02. 函数表达式方式(匿名函数)不行
const runAsyncTask = (callback) => {
if (typeof queueMicrotask === 'function') {
queueMicrotask(callback)
} else if (typeof MutationObserver === 'function') {
const obs = new MutationObserver(callback)
const divNode = document.createElement('div')
obs.observe(divNode, { childList: true })
divNode.innerHTML = 'hello world'
} else {
setTimeout(callback, 0)
}
}
const pp01 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(1111111)
}, 1000)
})
pp01
.then(
(res) => {
console.log(res)
return 22222222
},
(rej) => {
console.log(rej)
}
)
.then(
(res) => {
console.log(res)
return 33333333
},
(rej) => {
console.log(rej)
}
)
// ----------------------------测试MyPromise.any------------------
// const p00001 = new MyPromise((res, rej) => {
// setTimeout(() => {
// rej(1)
// }, 1000)
// })
// const p00002 = MyPromise.reject({ na: 123 })
// const p00003 = new MyPromise((res, rej) => {
// setTimeout(() => {
// // res(3)
// rej(3)
// }, 1000)
// })
// MyPromise.any([p00001, p00002, p00003]).then(
// (res) => {
// console.log('res', res)
// },
// (err) => {
// console.dir(err)
// }
// )
// ----------------------------测试MyPromise.allSettled------------------
// const p00001 = MyPromise.resolve(1)
// const p00002 = { na: 123 }
// const p00003 = new MyPromise((res, rej) => {
// setTimeout(() => {
// rej(3)
// }, 1000)
// })
// MyPromise.allSettled(new Set([p00001, p00002, p00003])).then(
// (res) => {
// console.log('res', res)
// },
// (err) => {
// console.log('err', err)
// }
// )
// ----------------------------测试MyPromise.all------------------
// Promise.all({})
// const p001 = new MyPromise((res, rej) => {
// setTimeout(() => {
// res(1)
// }, 2000)
// })
// const p002 = new MyPromise((res, rej) => {
// setTimeout(() => {
// // rej(222222222)
// res(111111111)
// }, 1000)
// })
// MyPromise.race([]).then(
// (res) => {
// console.log('res', res)
// },
// (err) => {
// console.log(err)
// }
// )
// 申明复杂数据类型的的变量指的是该地址 申明基本数据类型的变量指的是值本身
// const arr = [1, 2]
// const arr01 = arr
// arr01[1] = 3
// console.log(arr)
// console.log('arr01', arr01)
// let s1 = '123'
// let s2 = s1
// console.log('s2', s2)
// s2 = 3
// console.log('s1', s1)
// console.log('s2', s2)
// ----------------------------测试MyPromise.race------------------
// const p001 = new MyPromise((res, rej) => {
// setTimeout(() => {
// res(1)
// }, 2000)
// })
// const p002 = new MyPromise((res, rej) => {
// setTimeout(() => {
// rej(2)
// }, 1000)
// })
// MyPromise.race(new Set([p001, p002, 'ceshi'])).then(
// (res) => {
// console.log('res', res)
// },
// (err) => {
// console.log('err', err)
// }
// )
// ----------------------------测试MyPromise.resolve------------------
// MyPromise.resolve(
// new MyPromise((res, rej) => {
// setTimeout(() => {
// res(1111111111)
// }, 2000)
// }).then(
// (res) => {
// console.log('res', res)
// },
// (err) => {
// console.log('err', err)
// }
// )
// )
// MyPromise.resolve('123').then(
// (res) => {
// console.log('res', res)
// },
// (err) => {
// console.log('err', err)
// }
// )
// --------------------------------------------------------------
// MyPromise.resolve(
// new MyPromise((res, rej) => {
// res('res')
// // rej('rej')
// // throw 'error'
// })
// ).then(
// (res) => {
// console.log('res', res)
// },
// (rej) => {
// console.log('rej', rej)
// }
// )
// MyPromise.resolve('测试').then((res) => {
// console.log(res)
// })
// MyPromise.reject('测试error').catch((res) => {
// console.log(res)
// })
// ---------------------------------------------------
// console.log(new Error('我出错了01')) //Error: 我出错了01
// console.log(new Err('我出错了02')) //Uncaught ReferenceError: Err is not defined
// const p = new MyPromise((rel, rej) => {
// // setTimeout(() => {
// // rel('success0000000000')
// // // rej('err123456')
// // }, 1000)
// // rel('成功')
// // rej('failed')
// throw 'throw-error'
// })
// -------------------------辅助理解传入的回调函数----------------------
// const rel = () => {
// console.log('成功')
// }
// const rej = () => {
// console.log('失败')
// }
// const xxx = (rel, rej) => {
// // 省略逻辑
// rel()
// rej()
// }
// xxx(rel, rej)
// ----------------------------测试---------------------------------
// const p3 = p
// .then(
// (res) => {
// // throw 'erro'
// // return p3
// // return 2
// console.log(res)
// // return new MyPromise((resolve, reject) => {
// // resolve('Mp-3')
// // // reject('Mp-error')
// // })
// }
// // (err) => {
// // console.log('err1111', err)
// // // throw 'erro'
// // // return p3
## // // // return 2
// // // return new MyPromise((resolve, reject) => {
// // // // resolve('Mp-3')
// // // reject('Mp-error')
// // // })
// // }
// )
// .catch((err) => {
// console.log('catch', err)
// })
// .finally(() => {
// console.log('finally')
// })
// p3.then(
// (res) => {
// console.log('p3-res', res)
// },
// (err) => {
// console.log('p3-err', err)
// }
// )
// .then(
// (res) => {
// console.log('success02', res)
// return 200
// },
// (err) => {
// console.log('failed02', err)
// }
// )
// console.log(111)
// console.log(p)
// ----------------------------异步核心api函数-----------------------------
// queueMicrotask(() => {
// console.log(222)
// })
// const obs = new MutationObserver(() => {
// console.log(333)
// })
// const divNode = document.createElement('div')
// obs.observe(divNode, { childList: true })
// divNode.innerHTML = 'hello world'
// ----------------------原生Promise-----------------------------
// const pro = new Promise((s, r) => {
// s(0)
// })
// const pro01 = pro.then((res) => {
// return pro01
// })
// pro01.then((res) => {})
</script>