性能调优
- 优化异步任务调度算法:
- 策略:使用
async/await
结合Promise.allSettled
或Promise.race
来更好地控制并发任务。Promise.allSettled
可以等待所有任务完成(无论成功或失败),而Promise.race
可以在第一个任务完成时就返回结果。这样可以避免不必要的等待,提高执行效率。
- 代码示例:
// 使用Promise.allSettled
async function asyncTasks() {
const task1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Task 1 completed');
}, 1000);
});
const task2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Task 2 completed');
}, 1500);
});
const results = await Promise.allSettled([task1, task2]);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Task ${index + 1} succeeded:`, result.value);
} else {
console.log(`Task ${index + 1} failed:`, result.reason);
}
});
}
asyncTasks();
// 使用Promise.race
async function asyncTasksRace() {
const task1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Task 1 completed');
}, 1000);
});
const task2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Task 2 completed');
}, 1500);
});
const firstResult = await Promise.race([task1, task2]);
console.log('First completed task:', firstResult);
}
asyncTasksRace();
- 合理使用缓存:
- 策略:利用
WeakMap
或普通对象作为缓存。对于频繁调用且结果不经常变化的函数,可以缓存其返回值。对于类对象的方法调用结果缓存,可以在类实例中维护一个缓存对象。对于闭包模块,可以在闭包内部维护一个缓存变量。
- 代码示例:
// 使用普通对象缓存函数结果
const cache = {};
function expensiveCalculation(a, b) {
const key = `${a}-${b}`;
if (cache[key]) {
return cache[key];
}
const result = a + b;
cache[key] = result;
return result;
}
// 使用WeakMap缓存类对象方法结果
const instanceCache = new WeakMap();
class MyClass {
expensiveMethod() {
if (!instanceCache.has(this)) {
const result = /* 复杂计算 */ 42;
instanceCache.set(this, result);
}
return instanceCache.get(this);
}
}
内存管理
- 避免闭包引起的内存泄漏:
- 策略:确保在闭包不再需要时,切断对外部变量的引用。如果在类的方法中使用闭包,要注意在适当的时候(如类实例销毁时),清除闭包内部对类实例的引用。
- 代码示例:
class LeakyClass {
constructor() {
this.data = 'Some large data';
}
// 可能导致内存泄漏的闭包
createLeakyClosure() {
return () => {
return this.data;
};
}
}
class FixedClass {
constructor() {
this.data = 'Some large data';
}
createSafeClosure() {
const self = this;
return () => {
const temp = self.data;
// 清除引用
self = null;
return temp;
};
}
}
- 及时释放资源:
- 策略:对于使用
setTimeout
、setInterval
等创建的定时器,在不需要时要及时清除。对于事件监听器,在不再需要监听时要移除。
- 代码示例:
// 清除定时器
let timer;
function startTimer() {
timer = setTimeout(() => {
console.log('Timer executed');
}, 1000);
}
function stopTimer() {
clearTimeout(timer);
}
// 移除事件监听器
const button = document.getElementById('myButton');
function handleClick() {
console.log('Button clicked');
}
button.addEventListener('click', handleClick);
// 移除事件监听器
button.removeEventListener('click', handleClick);