<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script>
// @author NJJ
// 仿写Promise
// @author NJJ
// @description 解析Promise返回值
// @param p 表示上次的Promise 实例
// @param proValue 上一次的值
// @param resolve then 返回Promise中的 resolve
// @param reject then返回Promise中的 reject
const depthResolvePromise = function (p, proValue, resolve, reject) {
if (p === proValue) {
throw new TypeError("the same instance cannot be referenced cyclically ")
}
if (isObject(preValue) || typeof preValue === "function") {
if (typeof proValue.then === 'function') {
try {
then.call(
preValue,
y => {
depthResolvePromise(p, y, resolve, reject);
},
r => {
depthResolvePromise(p, r, resolve, reject);
}
)
} catch (e) {
reject(e);
}
} else {
resolve(proValue)
}
} else {
resolve(proValue)
}
}
// @author NJJ
// 判断对象是否为Promise对象
const isObject = function (value) {
Object.prototype.call(value) === '[object Object]'
}
const isPromise = function (obj) {
(isObject(obj) || typeof obj === 'function') && typeof obj.then === 'function'
}
// @author NJJ
// Promise状态参数
// 表示Promise三种状态的判定值
PromiseState = {
Peding: 'Peding',
Fulfilled: 'Fulfilled',
Rejected: 'Rejected'
}
// @author NJJ
// Promise的构造函数
// @param execution 构造器函数
function Promise2(execution) {
//设置初始状态为待定
this.value = ''
this.reason = ''
this.state = PromiseState.Peding
//为应对异步情况,将函数收集起来
this.fulfiledCallback = []
this.rejectedCallback = []
//Promise的resolve构造函数函数
const resolveFn = value => {
if (value instanceof Promise2) return value.Promise2((resolve, reject))
//如果状态不为待定则直接返回
if (this.state !== PromiseState.Peding) return;
//赋值并修改Promise的状态为成功
this.value = value
this.state = PromiseState.Fulfilled
this.fulfiledCallback.forEach(fn => fn(this.value))
}
//Promise的reject构造函数
const rejectFn = reason => {
//如果状态不为待定则直接返回
if (this.state !== PromiseState.Peding) return;
//赋值并修改Promise的状态为失败
this.reason = reason
this.state = PromiseState.Rejected
this.rejectedCallback.forEach(fn => fn(this.reason))
}
try {
execution(resolveFn, rejectFn)
} catch (e) {
rejectFn(e);
}
}
//@author NJJ
//@param onFulfiled resolve执行函数
//@param onRejected reject执行函数
//Promise.prototype.then方法
Promise2.prototype.then = function (onFulfiled, onRejected) {
//判断参数是否为函数
if (typeof onFulfiled !== 'function') onFulfiled = x => x
if (typeof onRejected !== 'function') {
onRejected = (err) => {
throw err
}
}
//在state为Fulfile和Rejected状态时,返回一新的Promise对象
if ([PromiseState.Fulfilled, PromiseState.Rejected].includes(this.state)) {
const p = new Promise((resolve, reject) => {
queueMicrotask(() => {
try {
const r =
this.state === PromiseStatus.Fulfilled ?
onFulfilled(this.value) :
onRejected(this.reason)
depthResolvePromise(p, r, resolve, reject)
} catch (e) {
reject(e)
}
});
});
return p;
}
//在状态为Peding时收集参数存入数组,等待异步结果
const p = new Promise((resolve, reject) => {
this.fulfilledCallback.push(value => {
queueMicrotask(() => {
try {
const r = onFulfilled(value);
depthResolvePromise(p, r, resolve, reject);
} catch (e) {
reject(e);
}
});
});
this.rejectedCallback.push(reason => {
queueMicrotask(() => {
try {
const r = onRejected(reason);
depthResolvePromise(p, r, resolve, reject);
} catch (e) {
reject(e)
}
});
});
});
return p;
};
// @author NJJ
// @description 直接返回一个成功状态的promise
// @param params 传递参数
// @returns {Promise}
Promise2.resolve = function (params) {
return new Promise(resolve => {
resolve(params)
})
}
// @author NJJ
// @description 直接返回一个失败状态的promise
// @param params 传递参数
// @returns {Promise}
Promise2.reject = function (params) {
return new Promise((_, reject) => {
reject(params)
})
}
// @author NJJ
// @description 返回一个promise的状态,无论是成功还是失败
// @param allPromise 表示所有的promise
Promise2.race = function (allPromise = []) {
return new Promise((resolve, reject) => {
let i = 0
for (; i < allPromise.length; i += 1) {
const item = allPromise[i]
if (!isPromise(item)) {
return resolve(item);
} else {
item.then(resolve, reject)
return
}
}
})
}
// @author lihh
// @description 多个promise同时发出请求,如果结果全部成功, 以数组的形式全部返回
// @param promiseAll promise 数组
// @returns {Promise} 返回的promise
Promise2.all = function (promiseAll = []) {
return new Promise((resolve, reject) => {
const resultArr = []
let count = 0
const callback = (index, res) => {
count += 1
resultArr[index] = res
if (count >= promiseAll.length) {
resolve(resultArr)
}
};
for (let i = 0; i < promiseAll.length; i += 1) {
const p = promiseAll[i]
if (!isPromise(p)) {
callback(i, p)
} else {
p.then(res => {
callback(i, res);
}, reject)
}
}
})
}
// @author NJJ
// @description 批量执行promise数组 无论是成功还是失败都会返回 最后返回一个promise
// 返回结构是: {status: 'fulfilled/ rejected',vakue}
// @param allPromise 传递参数
Promise2.allSettled = function (allPromise = []) {
return new Promise(resolve => {
let count = 0;
const resultArr = []
const callback = (index, value, status) => {
resultArr[index] = {
status,
value
}
count += 1;
if (count >= allPromise.length) {
resolve(resultArr);
}
}
allPromise.forEach((item, index) => {
if (!isPromise(item)) {
callback(index, item, "fulfilled")
} else {
item.then(
res => {
callback(index, res, "fulfilled")
},
err => {
callback(index, err, "rejected")
}
)
}
})
})
}
// @author NJJ
// @description 出现第一个成功状态 或是 如果所有的 promise 状态都失败了,则返回失败的状态
// @param allPromise 表示所有的promise
Promise2.any = function (allPromise) {
return new Promise((resolve, reject) => {
let count = 0
const rejectedCallback = () => {
count += 1
if (count >= allPromise.length) {
reject("[AggregateError: All promises were rejected]")
}
};
let i = 0
for (; i < allPromise.length; i += 1) {
const item = allPromise[i];
if (!isPromise(item)) {
return resolve(item)
} else {
item.then(
res => {
return resolve(res)
},
() => {
rejectedCallback()
}
)
}
}
})
}
Promise2.prototype.catch = function (fn) {
return this.then(null, fn);
}
Promise2.prototype.finally = function (fn) {
try {
fn()
return this.then(null, null);
} catch (e) {
const callback = () => {
throw e;
}
return this.then(callback, callback)
}
}
</script>
</html>
仿写Promise函数原理
最新推荐文章于 2024-05-30 11:27:58 发布