返回
Promise改造:在超时内,无论多个实例成功或失败都进入resolved状态
前端
2024-02-15 19:27:08
Promise增加超时功能
在原有Promise的基础上增加超时功能,当一个Promise在规定时间内没有被resolved或rejected,则自动触发超时,并以超时为由reject这个Promise。
实现原理
// 1.定义函数 promisifyWithTimeout
const promisifyWithTimeout = (promise, timeoutMs) => {
// 2.创建新的Promise
return new Promise((resolve, reject) => {
// 3.开启定时器,如果超过指定时间,则reject
const timeoutId = setTimeout(() => {
reject(new Error('Promise timed out'));
}, timeoutMs);
// 4.使用Promise.race来竞争两者谁先完成
Promise.race([
promise, // 原有的Promise
new Promise((resolve, reject) => { // 超时Promise
setTimeout(() => {
resolve('Promise timed out'); // 超时后resolve
}, timeoutMs);
})
])
.then(
// 5.如果原有Promise先完成,则resolve
(result) => {
clearTimeout(timeoutId); // 清除定时器
resolve(result); // resolve原有Promise的结果
},
// 6.如果超时Promise先完成,则reject
(reason) => {
clearTimeout(timeoutId); // 清除定时器
reject(reason); // reject超时的理由
}
);
});
};
// 7.使用示例
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('成功');
}, 2000);
});
promisifyWithTimeout(myPromise, 1000)
.then((result) => {
console.log(result); // '成功'
})
.catch((reason) => {
console.log(reason); // 'Promise timed out'
});
改造Promise.all,确保所有实例都执行完毕
实现原理
将Promise.all重写为:
Promise.allSettled = function (promises) {
return new Promise((resolve, reject) => {
let results = [];
let completed = 0;
promises.forEach((promise, i) => {
promise.then(
(value) => {
results[i] = { status: 'fulfilled', value };
if (++completed === promises.length) {
resolve(results);
}
},
(reason) => {
results[i] = { status: 'rejected', reason };
if (++completed === promises.length) {
resolve(results);
}
}
);
});
});
};
// 使用示例
const promise1 = Promise.resolve(3);
const promise2 = Promise.reject(2);
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 2000);
});
Promise.allSettled([promise1, promise2, promise3])
.then((results) => {
console.log(results);
// 结果:[
// { status: 'fulfilled', value: 3 },
// { status: 'rejected', reason: 2 },
// { status: 'fulfilled', value: 1 }
// ]
});