Promise.all
实现Promise.all方法:
- 接收一个可迭代对象(如数组),返回一个新 Promise;
- 所有 Promise 都成功时,返回结果数组(顺序和输入一致);
- 任意一个 Promise 失败时,立即返回该失败原因;
- 若输入为空数组,立即 resolve 空数组。
js
const myPromiseAll = (arrFunc) => {
return new Promise((resolve, reject) => {
let resArr = [];
let len = arrFunc.length;
let k = 0;
arrFunc.map((item, index) => {
Promise.resolve(item).then(
(res) => {
k++;
resArr[index] = res;
if (k === len) {
resolve(resArr);
}
},
(rej) => {
reject(rej);
}
);
});
});
};
const p1 = Promise.resolve(1);
const p2 = new Promise((resolve) => setTimeout(() => resolve(2), 1000));
const p3 = 3; // 非Promise值
myPromiseAll([p1, p2, p3])
.then((res) => {
console.log("all res:", JSON.stringify(res)); // [1,2,3]
})
.catch((err) => {
console.log("all err:", err);
});
Promise.race
实现Promise.race方法:
- 接收可迭代对象,返回新 Promise;
- 第一个完成(成功 / 失败)的 Promise 的结果 / 原因,就是最终结果;
- 若输入为空数组,永远 pending
js
const MyPromiseRace = (arrFunc) => {
return new Promise((resolve,reject) => {
arrFunc.map(item => {
Promise.resolve(item).then(res=>{
resolve(res)
},rej=>{
reject(rej)
})
});
});
};
const p1 = Promise.resolve(1);
const p2 = new Promise((resolve) => setTimeout(() => resolve(2), 1000));
const p3 = 3; // 非Promise值
const p4 = Promise.reject(new Error('fail'));
MyPromiseRace([p1, p4]).catch(err => {
console.log('all err:', err.message); // fail
});
Promise.allSettled
实现Promise.allSettled方法:
- 接收可迭代对象,返回新 Promise;
- 所有 Promise 都完成(成功 / 失败)后,返回结果数组;
- 每个结果对象格式:
{ status: 'fulfilled', value: xxx }或{ status: 'rejected', reason: xxx }; - 空数组立即 resolve 空数组
js
const MyPromiseAllSettled = (arrFunc)=>{
return new Promise((resolve,reject)=>{
let len = arrFunc.length
let resarr = []
let k = 0
arrFunc.map((item,index)=>{
Promise.resolve(item).then(res=>{
k++
resarr[index] = res
if(len === k){
resolve(resarr)
}
},rej=>{
k++
resarr[index] = rej
if(len === k){
resolve(resarr)
}
})
})
})
}
const p1 = Promise.resolve(1);
const p2 = new Promise((resolve) => setTimeout(() => resolve(2), 1000));
const p3 = 3; // 非Promise值
const p4 = Promise.reject(new Error('fail'));
MyPromiseAllSettled([p1,p2,p3, p4]).then(res => {
console.log('all err:', res); // fail
});
实现异步函数串行执行(基于 Promise)
给定一个异步函数数组(每个函数返回 Promise),实现一个函数,让这些函数串行执行(前一个完成后,再执行后一个),最终返回所有结果的数组。
js
const AsyncPromiseArr = (arrFunc) => {
return new Promise(async(resolve, reject) => {
const stack = [];
let i = 0
for(let func of arrFunc){
const res = await func();
stack.push(res);
i++
if(i === arrFunc.length){
resolve(stack)
}
}
});
};
// 测试用例
// 模拟异步函数
const task1 = () => new Promise(resolve => setTimeout(() => resolve(1), 500));
const task2 = () => new Promise(resolve => setTimeout(() => resolve(3), 1500));
const task3 = () => new Promise(resolve => setTimeout(() => resolve(2), 100));
AsyncPromiseArr([task1, task2, task3]).then(res => {
console.log('serial res:', res); // [1,2,3](执行顺序:task1→task2→task3)
});
实现 Promise 超时封装
实现一个函数withTimeout(promise, timeout, errMsg):
- 给 Promise 添加超时控制,若超过
timeout毫秒未完成,返回 reject(错误信息为errMsg); - 若 Promise 在超时前完成,正常返回结果;
- 超时后终止等待(无需取消原 Promise,仅控制返回结果)。
js
const withTimeout = (promise,timeout,errMsg)=>{
const promise1 = new Promise((resolve,reject)=>{
setTimeout(()=>reject(new Error(errMsg)),timeout)
})
return Promise.race([promise,promise1])
}
const p1 = new Promise(resolve => setTimeout(() => resolve(100), 500));
withTimeout(p1, 1000, '超时了').then(res => {
console.log('timeout res:', res); // 100
});
// 超时场景
const p2 = new Promise(resolve => setTimeout(() => resolve(200), 1500));
withTimeout(p2, 1000, '超时了').catch(err => {
console.log('timeout err:', err.message); // 超时了
});
实现一个防抖函数
触发事件后,第一次触发立即执行,后续延迟 n 毫秒执行回调函数 ;如果在这 n 毫秒内再次触发事件,重置延迟时间 ,同时增加cancel方法支持手动取消
js
const debounce_ = (fn,delay)=>{
let fn_
const debounceFunc = function(...args){
if(fn_){
clearTimeout(fn_)
}else{
fn.call(this,...args)
}
fn_ = setTimeout(()=>{
fn.call(this,...args)
fn_ = null
},delay)
}
debounceFunc.cancel = function(){
clearImmediate(fn_)
fn_ = null
}
return debounceFunc
}
function handleSearch(val) {
console.log('搜索:', val);
}
const debouncedSearchImmediate = debounce_(handleSearch, 1000);
debouncedSearchImmediate('a'); // 立即输出「搜索:a」
debouncedSearchImmediate('ab'); // 500ms内触发,重置定时器(无输出)
setTimeout(() => {
debouncedSearchImmediate('abc'); // 500ms后触发,立即输出「搜索:abc」
},2000);
// 测试取消功能
const debouncedCancel = debounce_(handleSearch, 500);
debouncedCancel('test');
debouncedCancel.cancel();
实现节流函数
触发事件后,每隔 n 毫秒只能执行一次回调函数,无论期间触发多少次,都会按固定频率执行
js
const throttle_ = (fn, delay) => {
let timer;
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
fn.call(this, ...args);
timer = null
}, delay);
}
};
};
实现带 Promise 的防抖函数
实现一个防抖函数debounceWithPromise(fn, delay):
- 触发后延迟
delay毫秒执行函数; - 重复触发时重置延迟;
- 函数执行结果通过 Promise 返回;
- 支持取消防抖(添加
cancel方法)。