完整代码
原生Promise 的用法
1.Promise 是 JavaScript 中用于处理异步操作的重要工具。它代表了一个异步操作的最终完成或失败,并且使异步方法可以像同步方法那样返回值。
- resolve:当异步操作成功时调用的函数,用于将 Promise 的状态改为 fulfilled,并将结果值传递给后续的 .then() 方法。
- reject:当异步操作失败时调用的函数,用于将 Promise 的状态改为 rejected,并将错误原因传递给后续的 .catch() 方法。
javascript
复制代码
const myPromise = new Promise((resolve, reject) => {
// 模拟异步操作,比如网络请求或文件读取
setTimeout(() => {
const success = true; // 假设操作成功
if (success) {
resolve('操作成功');
} else {
reject('操作失败');
}
}, 1000);
});
2. 使用 .then() 和 .catch()
- then():用于处理 Promise 成功时的回调函数。
- catch():用于处理 Promise 失败时的回调函数。
javascript
复制代码
myPromise
.then((value) => {
console.log(value); // 输出: 操作成功
})
.catch((error) => {
console.error(error); // 如果 Promise 被拒绝,这里会输出错误
});
3.使用 .finally().
- .finally():无论 Promise 成功还是失败,都会执行的回调函数,通常用于清理工作。
javascript
复制代码
myPromise
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
console.log('无论成功还是失败,都会执行这里');
});
4.静态方法
1. Promise.all()
- Promise.all():等待所有 Promise 都成功后,返回一个包含所有结果的数组。如果有一个 Promise 失败,则立即拒绝。
javascript
复制代码
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3])
.then((values) => {
console.log(values); // 输出: [1, 2, 3]
})
.catch((error) => {
console.error(error);
});
2. Promise.race()
- Promise.race():返回第一个完成的 Promise 的结果,无论是成功还是失败。
javascript
复制代码
const promise1 = new Promise((resolve) => setTimeout(resolve, 1000, '1'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 500, '2'));
Promise.race([promise1, promise2])
.then((value) => {
console.log(value); // 输出: 2(因为 promise2 先完成)
})
.catch((error) => {
console.error(error);
});
3.Promise.allSettled()
- Promise.allSettled():等待所有 Promise 都完成,无论成功还是失败,返回一个包含每个 Promise 状态和结果的数组。
javascript
复制代码
const promise1 = Promise.resolve(1);
const promise2 = Promise.reject(2);
const promise3 = Promise.resolve(3);
Promise.allSettled([promise1, promise2, promise3])
.then((results) => {
console.log(results);
// 输出:
// [
// { status: 'fulfilled', value: 1 },
// { status: 'rejected', reason: 2 },
// { status: 'fulfilled', value: 3 }
// ]
});
4.Promise.any()
- Promise.any():返回第一个成功完成的 Promise 的结果。如果所有 Promise 都失败,则返回一个包含所有错误的 AggregateError。
javascript
复制代码
const promise1 = Promise.reject(1);
const promise2 = Promise.reject(2);
const promise3 = Promise.resolve(3);
Promise.any([promise1, promise2, promise3])
.then((value) => {
console.log(value); // 输出: 3
})
.catch((errors) => {
console.error(errors);
});
手写promise 完整代码
scss
复制代码
const PROMISE_STATUS_PENDING = "pending";// Promise 状态:进行中
const PROMISE_STATUS_FULFILLED = "fulfilled";// Promise 状态:已成功
const PROMISE_STATUS_REJECTED = "rejected";// Promise 状态:已失败
/**
* 执行函数并捕获错误
* @param {Function} fn - 要执行的函数
* @param {any} value - 函数的参数
* @param {Function} resolve - 成功回调
* @param {Function} reject - 失败回调
*/
function execWithCatch(fn, value, resolve, reject) {
try {
const result = fn(value);
resolve(result);
} catch (error) {
reject(error);
}
}
/**
* SmPromise 类,模拟原生 Promise 的行为
*/
class SmPromise {
/**
* 创建一个 SmPromise 实例
* @param {Function} executor - 执行器函数,接收 resolve 和 reject 作为参数
*/
constructor(exector) {
this.status = PROMISE_STATUS_PENDING; // 初始状态为 pending
this.value = undefined; // 成功时的值
this.reason = undefined; // 失败时的原因
this.onFulfilledCallbacks = []; // 存储成功回调的数组
this.onRejectedCallbacks = []; // 存储失败回调的数组
/**
* 解决 Promise 的方法
* @param {any} value - Promise 成功的值
*/
const resolve = (value) => {
if (this.status == PROMISE_STATUS_PENDING) {
// 如果当前状态是 pending
queueMicrotask(() => {
// 使用微任务确保异步执行
if (this.status != PROMISE_STATUS_PENDING) return; // 如果状态已改变,直接返回
this.status = PROMISE_STATUS_FULFILLED; // 改变状态为 fulfilled
this.value = value; // 设置成功值
// 执行所有存储的成功回调
this.onFulfilledCallbacks.forEach((callback) => {
callback(this.value);
});
});
}
};
/**
* 拒绝 Promise 的方法
* @param {any} reason - Promise 失败的原因
*/
const reject = (value) => {
if (this.status == PROMISE_STATUS_PENDING) {
queueMicrotask(() => {
if (this.status != PROMISE_STATUS_PENDING) return;
this.status = PROMISE_STATUS_REJECTED; // 改变状态为 rejected
this.reason = value; // 设置失败原因
// 执行所有存储的失败回调
this.onRejectedCallbacks.forEach((callback) => {
callback(this.reason);
});
});
}
};
try {
// 执行用户传入的执行器函数
exector(resolve, reject);
} catch (error) {
// 如果执行器函数抛出异常,调用 reject 处理
reject(error);
}
}
/**
* Promise 链式调用方法
* @param {Function} onFulfilled - 成功时的回调函数
* @param {Function} onRejected - 失败时的回调函数
* @returns {SmPromise} 返回一个新的 SmPromise 实例
*/
then(onFulfilled, onRejected) {
// 设置默认的成功回调,如果没有传入则返回原值
const defaultOnFulfilled = (value) => value;
// 设置默认的失败回调,如果没有传入则抛出错误
const defaultOnRejected = (err) => { throw err;};
// 如果用户没有传入回调函数,则使用默认值
onRejected = onRejected ?? defaultOnRejected;
onFulfilled = onFulfilled ?? defaultOnFulfilled;
// 返回一个新的 Promise
return new SmPromise((resolve, reject) => {
/**
* 处理成功回调的函数
*/
const handleFulfilled = () => {
// 执行回调函数,并处理结果
execWithCatch(onFulfilled, this.value, resolve, reject);
};
/**
* 处理失败回调的函数
*/
const handleRejected = () => {
// 执行回调函数,并处理结果
execWithCatch(onRejected, this.reason, resolve, reject);
};
// 根据当前 Promise 的状态,执行相应的处理函数
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
// execWithCatch(onFulfilled, this.value, resolve, reject);
handleFulfilled()
}
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
handleRejected()
}
// 如果当前状态是 pending,将回调存储起来,等待状态改变后再执行
if (this.status === PROMISE_STATUS_PENDING) {
if (onFulfilled)
this.onFulfilledCallbacks.push(handleFulfilled);
if (onRejected)
this.onRejectedCallbacks.push(handleRejected);
}
});
}
/**
* 捕获 Promise 链中的错误
* @param {Function} onRejected - 错误处理函数
* @returns {SmPromise} 返回一个新的 SmPromise 实例
*/
catch(onRejected) {
// catch 等价于 then(undefined, onRejected)
return this.then(undefined, onRejected);
}
/**
* 无论 Promise 成功还是失败都会执行的回调
* @param {Function} onFinally - 最终执行的回调函数
* @returns {SmPromise} 返回一个新的 SmPromise 实例
*/
finally(onFinally) {
this.then(
() => {
onFinally();
},
() => {
onFinally();
}
);
}
/**
* 静态方法,返回一个已解决的 Promise
* @param {any} value - Promise 的值
* @returns {SmPromise} 返回一个已解决的 SmPromise 实例
*/
static resolve(value) {
return new SmPromise((resove) => resove(value));
}
/**
* 静态方法,返回一个已拒绝的 Promise
* @param {any} reason - Promise 拒绝的原因
* @returns {SmPromise} 返回一个已拒绝的 SmPromise 实例
*/
static reject(reason) {
return new SmPromise((resolve, reject) => reject(reason));
}
/**
* 静态方法,等待所有 Promise 完成
* @param {Array} promises - Promise 数组
* @returns {SmPromise} 返回一个新的 SmPromise 实例
*/
static all(promises) {
return new SmPromise((resolve, reject) => {
const allPrimiseResult = []; // 存储所有 Promise 的结果
promises.forEach((promise) => {
promise.then(
(res) => {
allPrimiseResult.push(res);
// 如果所有 Promise 都已完成,解决新的 Promise
if (allPrimiseResult.length === promises.length) {
resolve(allPrimiseResult);
}
},
(err) => {
reject(err); // 如果有 Promise 拒绝,新的 Promise 立即拒绝
}
);
});
});
}
/**
* 静态方法,等待所有 Promise 完成,无论成功还是失败
* @param {Array} promises - Promise 数组
* @returns {SmPromise} 返回一个新的 SmPromise 实例
*/
static allSettled(promises) {
return new SmPromise((resolve, reject) => {
const allPrimiseResult = []; // 存储每个 Promise 的状态和结果
let completedCount = 0; // 已完成的 Promise 数量
promises.forEach((promise, index) => {
SmPromise.resolve(promise)
.then(
(res) => {
// 保存成功状态和结果
allPrimiseResult[index] = {
status: PROMISE_STATUS_FULFILLED,
value: res,
};
},
(err) => {
// 保存失败状态和原因
allPrimiseResult[index] = {
status: PROMISE_STATUS_REJECTED,
err,
};
}
)
.then(() => {
completedCount++;
// 如果所有 Promise 都已完成,解决新的 Promise
if (completedCount === promises.length) {
resolve(results);
}
});
});
});
}
/**
* 静态方法,返回第一个完成的 Promise 的结果
* @param {Array} promises - Promise 数组
* @returns {SmPromise} 返回一个新的 SmPromise 实例
*/
static race(promises) {
return new SmPromise((resolve, reject) => {
// 遍历每个 Promise,第一个完成的将决定新的 Promise 的结果
promises.forEach((promise) => {
// promise.then(res => {
// resolve(res)
// }, err => {
// reject(err)
// })
SmPromise.resolve(promise).then(resolve, reject);
// promise.then(resolve, reject)
});
});
}
/**
* 静态方法,返回第一个成功完成的 Promise 的结果,如果所有都失败则返回 AggregateError
* @param {Array} promises - Promise 数组
* @returns {SmPromise} 返回一个新的 SmPromise 实例
*/
static any(promises) {
const errors = []; // 存储所有失败的原因
return new SmPromise((reslove, reject) => {
promise.forEach((promise) => {
promise.then(
(res) => {
// 如果有 Promise 成功,新的 Promise 立即解决
reslove(res);
},
(err) => {
errors.push(err); // 保存失败原因
if (errors.length === promises.length) {
// 如果所有 Promise 都失败,新的 Promise 拒绝
reject(new AggregateError(errors));
}
}
);
});
});
}
}