1 Star 0 Fork 0

Blake/js核心梳理

Create your Gitee Account
Explore and code with more than 12 million developers,Free private repositories !:)
Sign up
文件
This repository doesn't specify license. Please pay attention to the specific project description and its upstream code dependency when using it.
Clone or Download
22.手写Promise.html 7.04 KB
Copy Edit Raw Blame History
Blake authored 2024-02-21 12:40 . 第一次提交
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
// 将普通任务转换成异步 微任务
function createAsyncTask(task) {
if (typeof queueMicrotask === 'function') {
queueMicrotask(() => {
task()
})
} else {
setTimeout(() => {
task()
}, 0)
}
}
//抽取复用代码
function handleePromise(p2, x, resolve, reject) {
// 判断是不是循环引用(重复引用)
if (x === p2) {
throw new TypeError('Chaining cycle detected for promise #<Promise>')
}
// 判断x是不是promise实例对象
if (x instanceof MyPromise) {
x.then(
(res) => {
resolve(res)
},
(err) => {
reject(err)
}
)
} else {
resolve(x)
}
}
const PENDING = 'pending'
const REJECTED = 'rejected'
const FULFILLED = 'fulfilled'
// 类
class MyPromise {
#handles = [] // 私有属性 用来保存回调函数
// 构造函数
constructor(func) {
this.state = PENDING // 初始状态
this.result = undefined // 初始结果
const resolve = (result) => {
if (this.state === PENDING) {
this.state = FULFILLED
this.result = result
this.#handles.forEach((v) => {
v.onFulfilled()
})
}
}
const reject = (result) => {
if (this.state === PENDING) {
this.state = REJECTED
this.result = result
this.#handles.forEach((v) => {
v.onRejected()
})
}
}
try {
func(resolve, reject)
} catch (error) {
reject(error)
}
}
// 实例方法
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (x) => x
onRejected =
typeof onRejected === 'function'
? onRejected
: (x) => {
throw x
}
// then方法需要返回一个新的 Promise实例
const p2 = new MyPromise((resolve, reject) => {
if (this.state === FULFILLED) {
createAsyncTask(() => {
try {
// x是then的第一个形参函数的返回值
let x = onFulfilled(this.result)
handleePromise(p2, x, resolve, reject)
} catch (error) {
reject(error)
}
})
} else if (this.state === REJECTED) {
createAsyncTask(() => {
try {
// x是then的第一个形参函数的返回值
let x = onRejected(this.result)
handleePromise(p2, x, resolve, reject)
} catch (error) {
reject(error)
}
})
} else if (this.state === PENDING) {
// 解决异步 ,保存成功/失败回调函数
this.#handles.push({
onFulfilled: () => {
createAsyncTask(() => {
try {
// x是then的第一个形参函数的返回值
let x = onFulfilled(this.result)
handleePromise(p2, x, resolve, reject)
} catch (error) {
reject(error)
}
})
},
onRejected: () => {
createAsyncTask(() => {
try {
// x是then的第一个形参函数的返回值
let x = onRejected(this.result)
handleePromise(p2, x, resolve, reject)
} catch (error) {
reject(error)
}
})
}
})
}
})
return p2
}
catch(onRejected) {
// 内部调用then函数
return this.then(undefined, onRejected)
}
finally(onFinally) {
this.then(onFinally, onFinally)
}
// 静态方法
static resolve(value) {
if (value instanceof MyPromise) {
return value
}
return new Mypromise((resolve, reject) => {
resolve(value)
})
}
static reject(value) {
if (value instanceof MyPromise) {
return value
}
return new Mypromise((resolve, reject) => {
reject(value)
})
}
static race(promises) {
return new MyPromise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('argument is not iterable'))
}
promises.forEach((p) => {
MyPromise.resolve(p).then(
(res) => {
resolve(res)
},
(err) => {
reject(err)
}
)
})
})
}
static all(promises) {
return new MyPromise((resolve, reject) => {
// 判断参数是不是数组
if (!Array.isArray(promises)) {
return reject(new TypeError('argument is not iterable'))
}
// 空数组 直接兑现
promises.length == 0 && resolve(promises)
let resolves = []
let count = 0
promises.forEach((p, index) => {
MyPromise.resolve(p).then(
(res) => {
// 保证结果跟 Promise 数组参数顺序一致
resolves[index] = res
count++
count === promises.length && resolve(resolves) // 全部兑现之后,再兑现结果
},
(err) => {
reject(err)
}
)
})
})
}
}
// ---------------------------测试代码----------------------------------
const p1 = new MyPromise((resolve, reject) => {
resolve('1成功')
// reject('1错误')
// throw new Error('error')
// setTimeout(() => {
// resolve('1成功')
// }, 2000)
})
const p2 = p1
.then((res) => {
console.log('成功then1:', res)
// throw new Error('error')
return new MyPromise((resolve, reject) => {
setTimeout(() => {
reject(222)
}, 2000)
})
})
.catch((err) => {
console.log(err)
})
.finally(() => {
console.log('finally')
})
</script>
</body>
</html>
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/baiyujie02420/js-core-sorting.git
git@gitee.com:baiyujie02420/js-core-sorting.git
baiyujie02420
js-core-sorting
js核心梳理
main

Search